fix(oidc): constant-time PKCE code_challenge compare; validate nbf on at+jwt verifier #274

Merged
YousifShkara merged 1 commit from fix/BUNYIP-263-pkce-constant-time-nbf into main 2026-06-30 05:46:22 +02:00
Owner

BUNYIP-263: two narrow validation polish items the audit surfaced.

PKCE: consume_authorization_code compared challenge_computed != row.code_challenge with String !=, which short-circuits per byte. Both sides are deterministic SHA-256 base64url derivatives, so the practical leak surface is small, but constant-time compare is the canonical posture and subtle::ConstantTimeEq does it in two lines.

at+jwt verifier: verify_at_jwt_claims enabled validate_exp but not validate_nbf. An at+jwt with a future nbf (clock-skew replay, mint-side regression) was accepted at userinfo before its intended start time. The 30s leeway already absorbs normal clock drift; anything beyond that is a real signal worth blocking, so flipping validate_nbf = true costs nothing on the happy path and closes the gap.

Adds subtle = "2" as a bunyip-oidc dependency. No schema change, no mint-side change, no UX change.

#BUNYIP-263

BUNYIP-263: two narrow validation polish items the audit surfaced. PKCE: `consume_authorization_code` compared `challenge_computed != row.code_challenge` with String `!=`, which short-circuits per byte. Both sides are deterministic SHA-256 base64url derivatives, so the practical leak surface is small, but constant-time compare is the canonical posture and `subtle::ConstantTimeEq` does it in two lines. at+jwt verifier: `verify_at_jwt_claims` enabled `validate_exp` but not `validate_nbf`. An at+jwt with a future `nbf` (clock-skew replay, mint-side regression) was accepted at userinfo before its intended start time. The 30s leeway already absorbs normal clock drift; anything beyond that is a real signal worth blocking, so flipping `validate_nbf = true` costs nothing on the happy path and closes the gap. Adds `subtle = "2"` as a bunyip-oidc dependency. No schema change, no mint-side change, no UX change. #BUNYIP-263
fix(oidc): constant-time PKCE code_challenge compare; validate nbf on at+jwt verifier
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 20s
Check / fmt + clippy + build + tests (pull_request) Successful in 45m33s
Create release / Create release from merged PR (pull_request) Has been skipped
13ee3c16a9
BUNYIP-263: two narrow validation polish items the audit surfaced.

PKCE: `consume_authorization_code` compared `challenge_computed != row.code_challenge` with String `!=`, which short-circuits per byte. Both sides are deterministic SHA-256 base64url derivatives, so the practical leak surface is small, but constant-time compare is the canonical posture and `subtle::ConstantTimeEq` does it in two lines.

at+jwt verifier: `verify_at_jwt_claims` enabled `validate_exp` but not `validate_nbf`. An at+jwt with a future `nbf` (clock-skew replay, mint-side regression) was accepted at userinfo before its intended start time. The 30s leeway already absorbs normal clock drift; anything beyond that is a real signal worth blocking, so flipping `validate_nbf = true` costs nothing on the happy path and closes the gap.

Adds `subtle = "2"` as a bunyip-oidc dependency. No schema change, no mint-side change, no UX change.

#BUNYIP-263
YousifShkara deleted branch fix/BUNYIP-263-pkce-constant-time-nbf 2026-06-30 05:46:23 +02:00
Sign in to join this conversation.
No reviewers
No labels
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.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!274
No description provided.