Skip to content

security(auth): allowlist the emailed-link origin fallback (TODO 2) - #105

Open
lopugit wants to merge 9 commits into
developfrom
claude/todo2-verification-link-origin-s3
Open

security(auth): allowlist the emailed-link origin fallback (TODO 2)#105
lopugit wants to merge 9 commits into
developfrom
claude/todo2-verification-link-origin-s3

Conversation

@lopugit

@lopugit lopugit commented Jul 21, 2026

Copy link
Copy Markdown
Owner

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-configured APP_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_URL unset (local dev, preview, or a misconfigured prod env), the fallback returned new URL(request.url).origin verbatim — i.e., the caller-controlled Host header. A spoofed Host: attacker.com on 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 canonical https://thingtime.com for anything else. So an emailed token link can never point at a caller-controlled host, in any environment. (APP_URL still 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_URL precedence + 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, bare vercel.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

@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thingtime Ready Ready Preview Aug 9, 2026 2:53pm

Request Review

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

🧬 Rebased claude/todo2-verification-link-origin-s3 onto develop with the AI PR/stack rebase workflow.

  • Previous head: 7888e3e1eeb54e5363f8b5e9d597654d85987862
  • Rewritten head: 294f58fb64d45058787d104cf9335475d1386861
  • graphify: refreshed and committed (semantic mode: none)
  • Direct stacked children dispatched: 0

The branch was published once with an exact force-with-lease. Please review the rewritten commits before relying on them.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🤖 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.

Live status

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged develop into claude/todo2-verification-link-origin-s3 — conflicts auto-resolved by the resolve-pr-conflicts workflow.

No AI resolution was needed by merge time; the branch was updated with a plain merge commit.

graphify-out/ was reset wholesale to the develop side (repo rule: one side, never mixed — the graph merge driver is unavailable in CI).
Then re-ran graphify on the merged code WITH LLM semantic extraction (graphify extract, claude-cli backend) and committed the result — content new to this merge is semantically indexed; unchanged content came from the tracked cache.

Please review the merge commit before relying on it.

@github-actions github-actions Bot added the ai-rebase-in-progress AI stack rebase currently owns this PR branch label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🤖 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.

Live status

@lopugit
lopugit force-pushed the claude/todo2-verification-link-origin-s3 branch from 3946007 to 6aaf376 Compare August 9, 2026 08:52
@github-actions github-actions Bot removed the ai-rebase-in-progress AI stack rebase currently owns this PR branch label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🧬 Rebased claude/todo2-verification-link-origin-s3 onto develop with the AI PR/stack rebase workflow.

  • Previous head: 3946007d04c16fa276a53cc29e7c1b30a729b056
  • Rewritten head: 6aaf376387caa56405da4a35c2f43fc46d966e96
  • graphify: refreshed and committed (semantic mode: none)
  • Direct stacked children dispatched: 0

The branch was published once with an exact force-with-lease. Please review the rewritten commits before relying on them.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged develop into claude/todo2-verification-link-origin-s3 — conflicts auto-resolved by the resolve-pr-conflicts workflow.

No AI resolution was needed by merge time; the branch was updated with a plain merge commit.

graphify-out/ was reset wholesale to the develop side (repo rule: one side, never mixed — the graph merge driver is unavailable in CI).
Then re-ran graphify update (AST/text-only — the semantic extraction attempt failed this run; see the workflow log) and committed the result. Run graphify locally with an LLM backend if fresh semantic data is needed.

Please review the merge commit before relying on it.

@github-actions github-actions Bot added the ai-rebase-in-progress AI stack rebase currently owns this PR branch label Aug 9, 2026
lopugit and others added 3 commits August 9, 2026 11:51
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
@lopugit
lopugit force-pushed the claude/todo2-verification-link-origin-s3 branch from 3601d20 to 326ff17 Compare August 9, 2026 11:54
@github-actions github-actions Bot removed the ai-rebase-in-progress AI stack rebase currently owns this PR branch label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🧬 Rebased claude/todo2-verification-link-origin-s3 onto develop with the AI PR/stack rebase workflow.

  • Previous head: 3601d20d3e6edcc292e84b030179c1d083227cbd
  • Rewritten head: 326ff17481bae68f0c5aaf27919e825797a77a56
  • graphify: refreshed and committed (semantic mode: none)
  • Direct stacked children dispatched: 0

The branch was published once with an exact force-with-lease. Please review the rewritten commits before relying on them.

@lopugit lopugit added ai-rebase-paused AI stack rebase failed; manual retry or review required no-promote Never promote this develop PR to main no-ai-rebase Opt this PR's head branch out of AI history rewriting; the merge resolver owns its conflicts enhancement New feature or request labels Aug 9, 2026
@lopugit lopugit removed the ai-rebase-paused AI stack rebase failed; manual retry or review required label Aug 17, 2026
lopugit added a commit that referenced this pull request Aug 18, 2026
lopugit added a commit that referenced this pull request Aug 18, 2026
github-actions Bot added a commit that referenced this pull request Aug 18, 2026
github-actions Bot added a commit that referenced this pull request Aug 19, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 21, 2026
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
github-actions Bot added a commit that referenced this pull request Aug 24, 2026
github-actions Bot added a commit that referenced this pull request Aug 24, 2026
github-actions Bot added a commit that referenced this pull request Aug 24, 2026
github-actions Bot added a commit that referenced this pull request Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-merge-paused AI merge-conflict resolution failed; manual retry required enhancement New feature or request no-ai-rebase Opt this PR's head branch out of AI history rewriting; the merge resolver owns its conflicts no-promote Never promote this develop PR to main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant