Skip to content

OAuth web redirect fails with "Missing cookie." — __session lacks SameSite=None while the flow uses response_mode=form_post #2892

Description

@verveguy

Summary

The __session cookie set by /runtime/oauth/start carries no SameSite attribute, so Chrome applies its SameSite=Lax default. The web redirect flow uses response_mode=form_post, meaning the identity provider POSTs cross-site to /runtime/oauth/callback — and Chrome does not send Lax cookies on cross-site POSTs. The callback therefore answers:

{"type":"oauth-error","error":"Missing cookie."}

It presents as intermittent because of Chrome's "Lax + POST" mitigation, which still sends cookies less than two minutes old on top-level cross-site POSTs. A sign-in that completes quickly (an already-authenticated account chooser) succeeds; one that takes longer than two minutes — 2FA, or a passkey prompt — fails. That mitigation is being phased out, so the failure rate should be expected to rise.

Reproduction

The cookie, as sent today:

$ curl -s -D - -o /dev/null \
  "https://api.instantdb.com/runtime/oauth/start?app_id=<APP_ID>&client_name=google&redirect_uri=https%3A%2F%2Fexample.com%2F" \
  | grep -i set-cookie

set-cookie: __session=instantdb_3f0f8c95-...; HttpOnly; Secure; Expires=...; Path=/runtime/oauth

No SameSite. The same response's Location selects the form-post mode:

location: https://accounts.google.com/o/oauth2/v2/auth?...&response_mode=form_post&...

Isolating the cookie as the only variable, using a genuine state from that same start request (the invalid code is deliberate — the point is which check is reached):

# With the cookie: passes the cookie check, fails later on the bad code.
curl -s -X POST https://api.instantdb.com/runtime/oauth/callback \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H "Cookie: __session=instantdb_<from start>" \
  -d "code=probe-invalid&state=<from start>"
# (no "Missing cookie" error)

# Without it — what Chrome sends on a cross-site POST:
curl -s -X POST https://api.instantdb.com/runtime/oauth/callback \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "code=probe-invalid&state=<from start>"
{"type":"oauth-error","error":"Missing cookie."}

Expected

SameSite=None; Secure on the __session cookie, which is what a form_post flow requires. Secure is already set, so this should be a one-attribute change.

Alternatively, response_mode=query would keep the callback a top-level GET, where Lax cookies are sent — though that puts the authorization code in the URL, so the cookie attribute seems the better fix.

Environment

  • Chrome 152.0.7977.83, macOS
  • @instantdb/react / @instantdb/core 0.22.185 (client version is incidental — the cookie is set server-side by api.instantdb.com)
  • Web redirect flow via db.auth.createAuthorizationURL({ clientName, redirectURL }), per the Google OAuth web-redirect docs

Impact

Users who take longer than two minutes to authenticate — which includes anyone using a passkey or 2FA — cannot sign in with the web redirect flow at all, and the error surfaces as a raw JSON body rather than a redirect back to the app.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions