Skip to content

fix(security): drop wildcard CORS and reject cross-site tRPC POSTs - #21

Merged
luarss merged 1 commit into
mainfrom
fix/trpc-csrf-same-origin
Oct 28, 2026
Merged

luarss merged 1 commit into
mainfrom
fix/trpc-csrf-same-origin

Conversation

@luarss

@luarss luarss commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Why

/api/trpc shipped the starter-kit CORS block (Access-Control-Allow-Origin: *, Allow-Headers: *, an OPTIONS handler). The app is same-origin only, so this only widened the attack surface.

CSRF protection relied solely on iron-session's default SameSite=Lax. Lax treats every *.a5x.ai sibling as same-site, so XSS on another subdomain, or a subdomain takeover via a dangling CNAME, could send cookie-authenticated tRPC mutations. multipart/form-data is accepted by tRPC v11 and needs no preflight.

What

  • Remove setCorsHeaders and the OPTIONS export from the tRPC route.
  • Add isCrossSiteRequest() to server/utils/request.ts: non-GET/HEAD requests whose Sec-Fetch-Site is anything other than same-origin/none get a 403.
  • Requests without the header (SSR fetch, curl, scripts) pass through, so dev, Storybook (MSW), Playwright and server-side callers are unaffected.

Other /api/* routes are unchanged; they use their own token/bearer auth and some have external callers.

Tests

  • server/utils/__tests__/request.spec.ts: allowed vs. flagged Sec-Fetch-Site values, missing header, safe methods.
  • app/api/trpc/[trpc]/__tests__/route.spec.ts: cross-site POST → 403, same-origin passes through, no CORS headers or OPTIONS export.

Same patch applied across dev-kit, etp-compass, athena, etp-purser, etp-herald.

Remove the starter-kit Access-Control-Allow-Origin: * headers and OPTIONS
handler from /api/trpc; the app is same-origin only. Reject state-changing
requests whose Sec-Fetch-Site is not same-origin/none, closing the CSRF gap
that SameSite=Lax leaves open to sibling subdomains.
@luarss
luarss merged commit f56eab7 into main Oct 28, 2026
4 checks passed
@luarss
luarss deleted the fix/trpc-csrf-same-origin branch October 28, 2026 07:49
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.

1 participant