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

Open Beginner friendly
#2,892 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
typescript

Research direction

Start at the server-side handler for /runtime/oauth/start where the __session cookie is set, then check how /runtime/oauth/callback consumes it. Change the cookie to include SameSite=None while retaining Secure, and use the supplied curl requests to confirm the callback passes the cookie check without it failing after a cross-site POST.

Written by the indexing model from the issue text.

Description

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.

Dominant language
TypeScript
Stars
10.5k
Forks
408
Avg merge
4h 46m
Merged PRs (30d)
41

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from instantdb/instant

All issues in instantdb/instant

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.