BLOCKER: OIDC elevation must validate recent provider authentication #735

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

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

A2 — BLOCKER: OIDC does not prove recent authentication

Evidence at the base:

  • crates/calternal-auth/src/oidc.rs:119 starts reauthentication with the
    same authorization request as ordinary sign-in. It sets PKCE but no
    max_age and no reauthentication prompt.
  • crates/calternal-auth/src/oidc.rs:240 checks identity, a live session and
    the absence of passkeys, then records a fresh assertion. It does not check
    the ID token's auth_time.
  • crates/calternal-auth/src/api.rs:1919 also records a fresh assertion for
    each OIDC-only sign-in without checking authentication age.

Impact: a provider can reuse an old SSO session. A newly issued token proves
identity, but does not prove the recent User authentication required by
DESIGN §21. Authority changes can then pass the five-minute gate without
recent authentication. API and OIDC source are unchanged in round 7a.

Fix: request recent authentication for elevation and validate the signed
auth_time, with a bounded clock allowance. Fail closed for a missing,
stale, or future value. Do not mark an ordinary reused SSO login as asserted.
Preserve identity and local-session binding.

Required regression: extend the existing mock provider tests with recent,
missing, stale and future authentication times. Confirm that ordinary sign-in
still works and cannot by itself grant elevation.

Reference: OpenID Connect Core §§2 and 3.1.2.1.
max_age requests active authentication and requires an auth_time claim.

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. ### A2 — BLOCKER: OIDC does not prove recent authentication Evidence at the base: - `crates/calternal-auth/src/oidc.rs:119` starts reauthentication with the same authorization request as ordinary sign-in. It sets PKCE but no `max_age` and no reauthentication prompt. - `crates/calternal-auth/src/oidc.rs:240` checks identity, a live session and the absence of passkeys, then records a fresh assertion. It does not check the ID token's `auth_time`. - `crates/calternal-auth/src/api.rs:1919` also records a fresh assertion for each OIDC-only sign-in without checking authentication age. Impact: a provider can reuse an old SSO session. A newly issued token proves identity, but does not prove the recent User authentication required by DESIGN §21. Authority changes can then pass the five-minute gate without recent authentication. API and OIDC source are unchanged in round 7a. Fix: request recent authentication for elevation and validate the signed `auth_time`, with a bounded clock allowance. Fail closed for a missing, stale, or future value. Do not mark an ordinary reused SSO login as asserted. Preserve identity and local-session binding. Required regression: extend the existing mock provider tests with recent, missing, stale and future authentication times. Confirm that ordinary sign-in still works and cannot by itself grant elevation. Reference: [OpenID Connect Core §§2 and 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html). `max_age` requests active authentication and requires an `auth_time` claim. 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#735
No description provided.