Skip to content

Read the oauth handshake token from the cookie only - #329

Merged
umputun merged 4 commits into
masterfrom
oauth-handshake-cookie-only
Nov 9, 2026
Merged

umputun merged 4 commits into
masterfrom
oauth-handshake-cookie-only

Conversation

@umputun

@umputun umputun commented Nov 9, 2026

Copy link
Copy Markdown
Member

The oauth2, oauth1 and Apple callbacks read the handshake token with TokenService.Get, which takes the JWT query parameter and the X-JWT header before the cookie. A callback request could carry a handshake that the browser's own login step never set and complete a login started elsewhere, so the browser ended up signed in to an account it did not choose.

The callbacks now read the handshake from the JWT cookie only, through handshakeFromCookie in provider/service.go. It works on a copy of the request with the query and every header except Cookie removed, so the TokenService interface stays the same. Session tokens in the query or header work as before everywhere else.

Two related callback fixes in the same PR:

  • the oauth1 callback dereferenced a nil handshake when the cookie held a session token and GET was in XSRFIgnoreMethods, and the request panicked. It now answers 403 like the oauth2 and Apple callbacks.
  • Get skips the expiry check for cookies, so the 30-minute expiry the login handlers put on the handshake was never enforced. The callback now rejects a handshake whose expiry has passed. A handshake without an expiry is still accepted, the same in both modules.

Behavior change: a callback that sends the handshake in ?token= or X-JWT without the cookie now fails. No known integration does this: remark42 and _example finish OAuth through a browser popup with the cookie, and with SendJWTHeader the callback needed the cookie added in #262. A user who leaves the provider's consent page open for more than 30 minutes now has to start the login again.

Same changes in the root and v2 modules, with regression tests for each callback. The full request URL in callback error logs is a separate issue, recorded in docs/backlog/oauth-callback-error-log-keeps-query.md.

The oauth2, oauth1 and Apple callbacks read the handshake token with
TokenService.Get, which takes the JWT query parameter and header before
the cookie. A callback request could therefore carry a handshake that
the browser's own login step never set, and complete a login started
elsewhere.
The oauth1 callback read Handshake.State without checking that the
claims carry a handshake. A session cookie on the callback, with GET in
XSRFIgnoreMethods, made the request panic. It now answers 403 like the
oauth2 and Apple callbacks.
The login step gives the handshake a 30 minute expiry, but Get skips the
expiry check for cookies, so the callbacks accepted a handshake of any
age. The cookie-only lookup now rejects a token whose exp has passed.
A token without exp is still accepted, the same in both modules.
Copilot AI balanced review requested due to automatic review settings November 9, 2026 18:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@coveralls

coveralls commented Nov 9, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 42677216081

Coverage increased (+0.1%) to 87.062%

Details

  • Coverage increased (+0.1%) from the base build.
  • Patch coverage: 19 of 19 lines across 4 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 3880
Covered Lines: 3378
Line Coverage: 87.06%
Coverage Strength: 10.44 hits per line

💛 - Coveralls

@umputun
umputun merged commit fe47b52 into master Nov 9, 2026
8 of 9 checks passed
@umputun
umputun deleted the oauth-handshake-cookie-only branch November 9, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants