You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(auth): resolve confirmed findings from the Fable-5 security audit
Fixes 31 of 32 confirmed findings from the adversarially-verified ultracode audit
of the auth-ui rebuild; #16 is partially fixed with a documented residual. All
changes typecheck clean and pass the mirrored cypress component specs. See
docs/AUDIT-FINDINGS.md for the full per-finding detail and status.
Highlights by subsystem:
- session/device: device-authorization grants no longer auto-complete from the
forgeable GET /signed-in; they route to the CSRF-protected /device/authorize
consent screen (explicit Approve showing app + scope). (#10)
- rate-limit: limiters mount on '*' and self-guard on a normalized (lowercased,
.data-stripped) path, closing the case-variant and single-fetch bypasses. (#1, #11)
- verify: email-code resend is gated on server-verified session ownership and never
500s / enumerates; requestId validated + encoded into the /authorize hand-back.
(#9, #25, #30)
- signup: registration policy (allowRegister/allowPassword/passkeysType) enforced in
the actions; duplicate-email responses emit a Set-Cookie (presence oracle closed,
content/size residual documented — #16); fingerprintId used instead of the MaxMind
token; requestId resumed on email-link complete. (#3, #4, #14, #16, #17)
- sso: guarded getSession/startIdpIntent (graceful branded errors, not 500s); LDAP
reauth cookie cleared; ProviderError on sign-in mapped to the branded page;
deviceTrackingToken threaded on auto-link. (#2, #5, #6, #13, #19, #20, #21)
- providers/mappers: U2F factor derived from the webAuthN proto factor (fixes the
U2F login loop); failedAttempts extracted with the proper schema; forceMfaLocalOnly
kept distinct from forceMfa. (#0, #7, #22)
- session cookie: dual-format (ISO/epoch) timestamp parsing in the eviction pre-pass
so the 2KB budget is respected. (#8)
- webauthn: real browsers without WebAuthn see the unsupported message instead of
submitting the Cypress fake credential. (#27)
- fraud: MaxMind token falls back to the cookie when it lands after the poll budget;
default-org cache keyed per service URL. (#28, #29)
- audit logging: raw loginName replaced with hashActor across OTP/webauthn/password
reset events. (#23, #24, #26)
- setup: safeParse on tampered skip params; TOTP register guarded. (#12, #31)
Verification (2026-07-04): the 12 findings applied in the prior batch were
independently re-verified (verifier + adversary per finding). 9 closed cleanly;
#10 (device-auth) was incomplete and #30 (resend test) was a regression — both
re-fixed here; #16 (signup enumeration) is partial, with the residual documented
and full closure (sessions-cookie encryption) deferred by owner decision.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017UhyUkaSmoNFax5wu2aHfi
0 commit comments