Skip to content

fix(state): log a digest of the OAuth state instead of the raw value - #138

Merged
allen0099 merged 1 commit into
masterfrom
fix/state-log-redaction
Sep 25, 2026
Merged

allen0099 merged 1 commit into
masterfrom
fix/state-log-redaction

Conversation

@allen0099

Copy link
Copy Markdown
Owner

Closes #107

Problem

StateManager logged the raw state, which comes straight from the OAuth callback query string:

  • consume_state() logged an unknown or expired state at WARNING, so a caller could embed CR/LF and write forged lines into the logs.
  • Valid state tokens ended up in production logs.
  • A malformed stored entry was logged twice at ERROR with a traceback. The pydantic validation error in that traceback echoed the stored data, including the state.

Change

  • Every log line identifies the state by state_ref, the first 12 hex characters of its SHA-256. An operator can compute it from a known state to find the matching lines.
  • consume_state() logs an unknown or expired state at INFO instead of WARNING.
  • _decode_state() no longer logs. Its callers (consume_state, validate_state, get_state_metadata) log a malformed entry once, at WARNING, without exc_info. consume_state() still raises StateDataError.
  • docs/STATE.md notes describe the logging behaviour, and there is a CHANGELOG entry under Fixed.

Not breaking: no public signature changes. Only log levels and log content change.

Tests

The new tests in tests/state/test_manager.py fail on the old code and pass with this change:

  • no raw state and no CR/LF in any record across the create, validate, consume and delete paths, including a forged state;
  • unknown or expired states stay below WARNING;
  • a malformed entry produces exactly one WARNING with no traceback, for each of consume, validate and metadata.

Full suite with live Redis and Memcached: 759 passed. The docs build passes with --strict.

The state comes straight from the callback query string. Logging it raw leaked
live tokens and let a caller forge log lines with CR/LF. Log lines now carry
state_ref (first 12 hex chars of its SHA-256). Unknown or expired states log
at INFO, and malformed stored data logs once at WARNING without a traceback.

Closes #107
@allen0099
allen0099 merged commit a260fee into master Sep 25, 2026
10 checks passed
@allen0099
allen0099 deleted the fix/state-log-redaction branch September 26, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

StateManager logs raw OAuth state values at WARNING

1 participant