BUG-HUNT: [security] Exception class names not redacted, could leak secrets #6951

Open
opened 2026-04-10 06:02:36 +00:00 by HAL9000 · 0 comments
Owner

Metadata

  • Branch: fix/security-exception-type-name-not-redacted
  • Commit Message: fix(error_handling): redact exception class name in classify_error to prevent secret leakage
  • Milestone: v3.5.0
  • Parent Epic: #400

Background and Context

The error handling module in src/cleveragents/core/error_handling.py carefully redacts secrets from error messages and details via redact_value(). However, the classify_error() function does not apply redaction to the exception class name (exception_type field of ErrorInfo).

If a developer creates a custom exception class with sensitive data embedded in the class name (e.g., class MyAPIKey_sk_12345_Error(Exception)), that secret would bypass all redaction and be stored and surfaced through the error handling system.

While this requires an unusual coding pattern, the security principle of defense in depth demands that all string fields in ErrorInfo pass through the same redaction pipeline.

Current Behavior

In classify_error() at lines 254–255 of src/cleveragents/core/error_handling.py:

return ErrorInfo(
    code=code,
    message=redact_value(str(exc)),  # Message is redacted ✓
    exception_type=type(exc).__name__,  # Class name is NOT redacted ✗
    details=details,
)

The exception_type field is populated directly from type(exc).__name__ without any redaction, potentially exposing secrets embedded in custom exception class names.

Expected Behavior

Exception class names should be passed through the same redact_value() redaction process as all other string fields in ErrorInfo, ensuring no secrets can leak through this vector:

return ErrorInfo(
    code=code,
    message=redact_value(str(exc)),
    exception_type=redact_value(type(exc).__name__),  # Apply redaction ✓
    details=details,
)

Acceptance Criteria

  • classify_error() applies redact_value() to type(exc).__name__ before assigning it to ErrorInfo.exception_type
  • A custom exception class whose name contains a known secret pattern has its class name redacted in the resulting ErrorInfo
  • All existing error handling tests continue to pass
  • No regression in normal exception class names (e.g., ValueError, KeyError) — these contain no secret patterns and pass through unchanged

Supporting Information

  • File: src/cleveragents/core/error_handling.py
  • Function: classify_error()
  • Lines: 254–255
  • Related issue: #4153 (sensitive data leaking via wrap_unexpected exception message — same redaction gap, different vector)
  • Security principle: Defense in depth — all string fields that may be surfaced to users or logs must be redacted

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it.

Subtasks

  • Reproduce the bug: create a custom exception with a secret-like class name and confirm ErrorInfo.exception_type is unredacted
  • Apply redact_value() to type(exc).__name__ in classify_error() at src/cleveragents/core/error_handling.py lines 254–255
  • Add/update BDD scenario in the error handling feature file to cover exception type name redaction
  • Add Robot Framework regression test tagged @tdd_issue and @tdd_issue_<issue-number>
  • Verify all nox stages pass
  • Confirm coverage ≥ 97%

Definition of Done

  • classify_error() wraps type(exc).__name__ with redact_value() before assigning to ErrorInfo.exception_type
  • BDD scenario added proving a secret-bearing exception class name is redacted in ErrorInfo.exception_type
  • Robot Framework regression test added with @tdd_issue and @tdd_issue_<issue-number> tags
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: new-issue-creator

## Metadata - **Branch**: `fix/security-exception-type-name-not-redacted` - **Commit Message**: `fix(error_handling): redact exception class name in classify_error to prevent secret leakage` - **Milestone**: v3.5.0 - **Parent Epic**: #400 ## Background and Context The error handling module in `src/cleveragents/core/error_handling.py` carefully redacts secrets from error messages and details via `redact_value()`. However, the `classify_error()` function does **not** apply redaction to the exception class name (`exception_type` field of `ErrorInfo`). If a developer creates a custom exception class with sensitive data embedded in the class name (e.g., `class MyAPIKey_sk_12345_Error(Exception)`), that secret would bypass all redaction and be stored and surfaced through the error handling system. While this requires an unusual coding pattern, the security principle of **defense in depth** demands that all string fields in `ErrorInfo` pass through the same redaction pipeline. ## Current Behavior In `classify_error()` at lines 254–255 of `src/cleveragents/core/error_handling.py`: ```python return ErrorInfo( code=code, message=redact_value(str(exc)), # Message is redacted ✓ exception_type=type(exc).__name__, # Class name is NOT redacted ✗ details=details, ) ``` The `exception_type` field is populated directly from `type(exc).__name__` without any redaction, potentially exposing secrets embedded in custom exception class names. ## Expected Behavior Exception class names should be passed through the same `redact_value()` redaction process as all other string fields in `ErrorInfo`, ensuring no secrets can leak through this vector: ```python return ErrorInfo( code=code, message=redact_value(str(exc)), exception_type=redact_value(type(exc).__name__), # Apply redaction ✓ details=details, ) ``` ## Acceptance Criteria - `classify_error()` applies `redact_value()` to `type(exc).__name__` before assigning it to `ErrorInfo.exception_type` - A custom exception class whose name contains a known secret pattern has its class name redacted in the resulting `ErrorInfo` - All existing error handling tests continue to pass - No regression in normal exception class names (e.g., `ValueError`, `KeyError`) — these contain no secret patterns and pass through unchanged ## Supporting Information - **File**: `src/cleveragents/core/error_handling.py` - **Function**: `classify_error()` - **Lines**: 254–255 - **Related issue**: #4153 (sensitive data leaking via `wrap_unexpected` exception message — same redaction gap, different vector) - **Security principle**: Defense in depth — all string fields that may be surfaced to users or logs must be redacted ### TDD Note After this bug issue is verified, a corresponding `Type/Testing` issue will be created for TDD. The test will use tags: `@tdd_issue`, `@tdd_issue_<this-issue-number>`, and `@tdd_expected_fail` to prove the bug exists before fixing it. ## Subtasks - [ ] Reproduce the bug: create a custom exception with a secret-like class name and confirm `ErrorInfo.exception_type` is unredacted - [ ] Apply `redact_value()` to `type(exc).__name__` in `classify_error()` at `src/cleveragents/core/error_handling.py` lines 254–255 - [ ] Add/update BDD scenario in the error handling feature file to cover exception type name redaction - [ ] Add Robot Framework regression test tagged `@tdd_issue` and `@tdd_issue_<issue-number>` - [ ] Verify all nox stages pass - [ ] Confirm coverage ≥ 97% ## Definition of Done - [ ] `classify_error()` wraps `type(exc).__name__` with `redact_value()` before assigning to `ErrorInfo.exception_type` - [ ] BDD scenario added proving a secret-bearing exception class name is redacted in `ErrorInfo.exception_type` - [ ] Robot Framework regression test added with `@tdd_issue` and `@tdd_issue_<issue-number>` tags - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: new-issue-creator
HAL9000 added this to the v3.5.0 milestone 2026-04-10 06:02:43 +00:00
HAL9000 self-assigned this 2026-04-10 06:21:49 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#400 Epic: Post-MVP Security
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#6951
No description provided.