Skip to content

fix: limit CORS to the API - #34

Merged
johnf merged 1 commit into
mainfrom
fix/scope-cors-to-api
Oct 27, 2026
Merged

johnf merged 1 commit into
mainfrom
fix/scope-cors-to-api

Conversation

@johnf

@johnf johnf commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Summary

CORS was registered on the whole app with any origin allowed. It now covers only /api.

 buildApp
-  cors (every route; HEAD GET POST PUT DELETE OPTIONS)
-  arocapi  { prefix: /api }
-  ldacapi  { prefix: /api }
+  /api scope
+    cors { origin: *, methods: GET HEAD POST, maxAge: 2h }
+    arocapi
+    ldacapi
   oidcProvider        # keeps its own per-client CORS
  • Any origin: the API authenticates with bearer tokens, never cookies, so a hostile site can only read what anyone can already fetch. No Access-Control-Allow-Credentials.
  • Methods: /api only serves GET, HEAD and POST (search).
  • maxAge 2h: every Oni request carries Authorization, so without it each one is preceded by a preflight (Chrome caches preflights for 5s by default and caps them at 2h).
  • Routes outside /api (the OIDC provider, and the admin pages when they land) get no CORS headers.

Evidence

  • Before: the two new tests in src/app.test.ts fail.
    • OPTIONS /api/search preflight → no max-age, methods include PUT, DELETE
    • OPTIONS /admin/ from another origin → access-control-allow-origin: *
  • After: both pass. Full suite 103/103, pnpm lint clean.

Merge Danger

Door: two-way

Blast Radius: small

Browser clients only. A cross-origin client sending PUT or DELETE to /api would now fail its preflight, but no /api route accepts those methods anyway. Changes to the CORS policy can take up to 2h to reach browsers because of the preflight cache.

Only /api gets CORS headers, so the OIDC provider keeps its own
per-client CORS and future same-origin pages get none. Any origin may
call it: auth is by bearer token, never cookies. Methods are trimmed to
the ones the API serves, and preflights are cached for two hours.
@johnf
johnf requested a review from moisbo October 27, 2026 23:46
@johnf
johnf merged commit 3acefc5 into main Oct 27, 2026
4 checks passed
@johnf
johnf deleted the fix/scope-cors-to-api branch October 27, 2026 23:47
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