Surfaced by QA run #10663 (identity-auth.two-factor-enrollment-reveal) at 79ebb37. Existence + mechanism only; full reproduction withheld pending maintainer review per the auth/authz disclosure carve-out — available in the QA session on request.
What
POST /api/v1/auth/two-factor/verify-totp returns 200 with a rotated session cookie and a token field. The new cookie alone authenticates correctly; the new bearer alone does not (get-session 200 but empty, get-totp-uri 401), and cookie + bearer together also 401 — the Authorization header wins and drops the request to anonymous. Fail-closed (no privilege gained), but a legitimate user is locked out.
Impact
Any client that stores the token from the 2FA-completion response — exactly the console's auth-session-token pattern — is unauthenticated after a 2FA sign-in, and its still-valid cookie cannot rescue it (the header takes precedence). A convincing "2FA sign-in silently breaks my session" for header/bearer-based clients.
Mechanism (fix-oriented)
The token echoed by verify-totp is not a usable bearer credential, and the request resolver prefers the Authorization header over the (valid) cookie, so presenting the dud bearer downgrades an otherwise-authenticated request. Fix direction: either return a bearer that is actually accepted, or have the resolver fall back to the cookie when the bearer is unusable rather than dropping to anonymous.
QA-source: #10663 · identity-auth.two-factor-enrollment-reveal · adjacent finding (verify-totp token seam)
Surfaced by QA run #10663 (
identity-auth.two-factor-enrollment-reveal) at79ebb37. Existence + mechanism only; full reproduction withheld pending maintainer review per the auth/authz disclosure carve-out — available in the QA session on request.What
POST /api/v1/auth/two-factor/verify-totpreturns 200 with a rotated session cookie and atokenfield. The new cookie alone authenticates correctly; the new bearer alone does not (get-session200 but empty,get-totp-uri401), and cookie + bearer together also 401 — the Authorization header wins and drops the request to anonymous. Fail-closed (no privilege gained), but a legitimate user is locked out.Impact
Any client that stores the token from the 2FA-completion response — exactly the console's
auth-session-tokenpattern — is unauthenticated after a 2FA sign-in, and its still-valid cookie cannot rescue it (the header takes precedence). A convincing "2FA sign-in silently breaks my session" for header/bearer-based clients.Mechanism (fix-oriented)
The token echoed by
verify-totpis not a usable bearer credential, and the request resolver prefers the Authorization header over the (valid) cookie, so presenting the dud bearer downgrades an otherwise-authenticated request. Fix direction: either return a bearer that is actually accepted, or have the resolver fall back to the cookie when the bearer is unusable rather than dropping to anonymous.QA-source: #10663 · identity-auth.two-factor-enrollment-reveal · adjacent finding (verify-totp token seam)