security(auth): allowlist the emailed-link origin fallback (TODO 2) - #105
security(auth): allowlist the emailed-link origin fallback (TODO 2)#105lopugit wants to merge 9 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
7888e3e to
294f58f
Compare
|
🧬 Rebased
The branch was published once with an exact force-with-lease. Please review the rewritten commits before relying on them. |
|
🤖 Auto-resolve running — the conflict resolver started working on this PR at 14:28 UTC. Expected to finish around 14:36 UTC (resolutions typically land in 3-8 minutes; the job times out at 30). On success a merge commit resolving the conflicts is pushed to this branch and a result comment follows — no manual action is needed meanwhile. |
|
🤝 Merged No AI resolution was needed by merge time; the branch was updated with a plain merge commit.
Please review the merge commit before relying on it. |
|
🤖 Auto-rebase running — the stack rebase started working on this PR at 11:50 UTC. Expected to finish around 12:05 UTC (rebases typically land in 5-15 minutes; the job times out at 55). On success this branch is force-pushed onto its new base and a result comment follows — no manual action is needed meanwhile. |
3946007 to
6aaf376
Compare
|
🧬 Rebased
The branch was published once with an exact force-with-lease. Please review the rewritten commits before relying on them. |
|
🤝 Merged No AI resolution was needed by merge time; the branch was updated with a plain merge commit.
Please review the merge commit before relying on it. |
resolveTrustedOrigin already preferred APP_URL (the main TODO 2 ask, shipped earlier), but with APP_URL unset the fallback trusted the raw request origin -- a spoofed Host header could still steer verification / password-reset links (with their single-use tokens) to an attacker origin in any environment missing APP_URL. The fallback now only returns the request origin for hosts we actually deploy to (localhost, 127.0.0.1, *.thingtime.com, *.vercel.app, *.ts.net); anything else gets the canonical https://thingtime.com, so an emailed link can never point at a caller-controlled host. Verified by a 12-case node suite against the shipped source, including lookalike hosts (evil-thingtime.com, thingtime.com.evil.com, bare vercel.app, ats.net) all resolving to the canonical origin. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AST/text-only `graphify update` (graphify 0.9.4, no semantic extraction); run graphify locally with an LLM backend if semantic data is needed. Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/31311432158
Refreshed by the rebase-pr-stacks workflow: https://github.com/lopugit/thingtime/actions/runs/31311662374
3601d20 to
326ff17
Compare
|
🧬 Rebased
The branch was published once with an exact force-with-lease. Please review the rewritten commits before relying on them. |
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
…n fallback (TODO 2)
Finishes TODO 2 — Tighten verification-link origin trust.
Context
Most of TODO 2 had already shipped:
resolveTrustedOrigin(remix/app/api/utils/auth/appOrigin.ts) prefers the server-configuredAPP_URL, and all four emailed-link routes (register, resend-verification, password-reset, service-account) go through it. The TODO's "links are still built from the request origin" wording predates that util.The residual gap
With
APP_URLunset (local dev, preview, or a misconfigured prod env), the fallback returnednew URL(request.url).originverbatim — i.e., the caller-controlled Host header. A spoofedHost: attacker.comon a password-reset or registration POST would email the victim a real link pointing at the attacker, leaking the single-use token on click.The fix
The fallback now only trusts hosts we actually deploy to —
localhost,127.0.0.1,*.thingtime.com,*.vercel.app,*.ts.net— and returns the canonicalhttps://thingtime.comfor anything else. So an emailed token link can never point at a caller-controlled host, in any environment. (APP_URLstill wins outright when set; setting it in Vercel prod bypasses the fallback entirely and is still recommended.)Verification
12-case node suite run against the shipped source (extracted verbatim):
APP_URLprecedence + trailing-slash trim; all five trusted host classes keep their request origin (ports included); and hostile/lookalike hosts —attacker.com,evil-thingtime.com,thingtime.com.evil.com, barevercel.app,ats.net— all resolve to the canonical origin. All pass.Also annotates TODO 2 as fixed in
TODO/TODO.md(single-hunk edit).Session 3 of 10 parallel todo sessions (previous: #94 TODO 9, #102 TODO 10); claim branch pushed before work started.
🤖 Generated with Claude Code