fix(exousia): harden auth paths (constant-time keys, DB-authoritative bearer, refresh TOCTOU) - #476
Merged
Merged
Conversation
… bearer, refresh TOCTOU) - #473: constant-time API-key hash comparison via subtle::ConstantTimeEq; the plain == on hex digests leaked a timing side-channel. - #418: validate_bearer now fetches the user row and takes role + is_active from the DB, not the JWT claim, so revocation and role demotion take effect within a token's lifetime (matching validate_api_key). The JWT is authoritative for identity only. - #419: refresh() runs read-check-revoke-insert inside one BEGIN IMMEDIATE transaction on the single-writer pool, closing the refresh-token double-use TOCTOU. Adds apotheke begin_immediate/commit_tx helpers and generalizes the refresh-token repo fns over an Executor. - #420: remove the ?token= query-param auth path (credential-in-URL leak); grep confirmed no consumer. Drops AuthMethod::QueryParam. Closes #473 Closes #418 Closes #419 Closes #420 Gate-Passed: kanon 0.1.5 +stages:fmt,check,clippy,nextest,lint sha:79d6e7cb5466037cf22e6b409e3730ca0bbb199c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #473, #418, #419, #420.
Changes
validate_api_keycompared SHA-256 hex digests with==, leaking a timing side-channel on an auth path. Now usessubtle::ConstantTimeEq. Class-swept the crate for other secret==comparisons (none remained). Near-miss + empty-hash tests added.validate_bearertrusted the JWTroleclaim and never re-checked the user, diverging fromvalidate_api_key. It now fetches the user row and takesrole+is_activefrom the DB, so revocation and role demotion take effect within a token's lifetime. The JWT is authoritative for identity only. Tests: role-demotion-reflected, deactivated-user-rejected, deleted-user-rejected.refresh()ran read-check-revoke-insert as three unsynchronized statements across pools, allowing double-use under concurrency. Now oneBEGIN IMMEDIATEtransaction on the single-writer pool (adds apothekebegin_immediate/commit_txand generalizes the refresh-token repo fns over anExecutor). Concurrent-double-use test asserts exactly one success and no orphaned rows.?token=) places credential in URIs — logs, history, Referer #420 — query-param token removal. The?token=path minted a full-duration bearer session; a repo-wide grep found no consumer (theatron usesbearer_authonly). Removedextract_query_token, its call site, andAuthMethod::QueryParam. Docs updated to describe the header-only model and the short-TTL stream-token precondition for any future URL-delivered credential.Verification
kanon gate --fullgreen (fmt, check, advisory-parity, cargo-deny, clippy workspace, nextest 1166 tests, kanon lint). Cross-crate: full-workspace clippy+test confirm archon and callers compile against the generalized apotheke signatures.