BLOCKER: Bound retained passkey and OIDC ceremony state #737

Open
opened 2026-10-02 13:06:56 +00:00 by kayg · 0 comments
Owner

Defensive sec-auth audit, base c4a61e8cf0, requested under #663. Source review only; no product edits.

A3 — BLOCKER: bound retained authentication challenges

Evidence: passkey.rs:76 removes expired entries and inserts a pending
challenge without a count or byte cap. api.rs:948 starts setup registration
without checking the setup token first. The pending registration retains the
supplied token in RegistrationGrant::Setup. The token is not length-bounded
here. The HTTP body limit bounds one request, not retained state across
requests. Login challenges use the same uncapped map. OIDC start_flow at
line 119 also has an uncapped pending map. Rate limits are per IP and do not
bound total resident state. Round 7a does not change these files.

Impact: unauthenticated input can retain memory across requests until expiry.
The Instance has no global resource bound for these ceremonies. Each insert
also scans the whole map to remove expired state. This is a reasoned resource
exhaustion finding; no memory or latency measurement is claimed.

Fix: cap pending count and retained bytes before allocating challenge state.
Validate setup grants, including token length and validity, before a ceremony.
Use bounded expiry work. Apply the same rule to OIDC pending state. Return a
controlled rate-limit response at capacity and preserve valid in-flight state.

Required regression: small configured caps for count and bytes; expiry frees
capacity; invalid setup grants allocate no pending state; concurrent admission
cannot exceed the cap. Keep data synthetic and local to unit tests.

Duplicate check: searched all issue states for authentication, recovery, re-enrolment, auth_time and challenge findings; no matching corrective issue found. Related #3 and #195 are broad auth and authorization work.

Defensive sec-auth audit, base c4a61e8cf090170f35b1bed3350d9de20c83ecd5, requested under #663. Source review only; no product edits. ### A3 — BLOCKER: bound retained authentication challenges Evidence: `passkey.rs:76` removes expired entries and inserts a pending challenge without a count or byte cap. `api.rs:948` starts setup registration without checking the setup token first. The pending registration retains the supplied token in `RegistrationGrant::Setup`. The token is not length-bounded here. The HTTP body limit bounds one request, not retained state across requests. Login challenges use the same uncapped map. OIDC `start_flow` at line 119 also has an uncapped pending map. Rate limits are per IP and do not bound total resident state. Round 7a does not change these files. Impact: unauthenticated input can retain memory across requests until expiry. The Instance has no global resource bound for these ceremonies. Each insert also scans the whole map to remove expired state. This is a reasoned resource exhaustion finding; no memory or latency measurement is claimed. Fix: cap pending count and retained bytes before allocating challenge state. Validate setup grants, including token length and validity, before a ceremony. Use bounded expiry work. Apply the same rule to OIDC pending state. Return a controlled rate-limit response at capacity and preserve valid in-flight state. Required regression: small configured caps for count and bytes; expiry frees capacity; invalid setup grants allocate no pending state; concurrent admission cannot exceed the cap. Keep data synthetic and local to unit tests. Duplicate check: searched all issue states for authentication, recovery, re-enrolment, auth_time and challenge findings; no matching corrective issue found. Related #3 and #195 are broad auth and authorization work.
Sign in to join this conversation.
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
kayg/calternal#737
No description provided.