Skip to content

chore: remove permissive CORS from server and master - #193

Merged
beinan merged 1 commit into
mainfrom
chore/remove-permissive-cors
Jul 25, 2026
Merged

chore: remove permissive CORS from server and master#193
beinan merged 1 commit into
mainfrom
chore/remove-permissive-cors

Conversation

@beinan

@beinan beinan commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

Both binaries wrapped their routers in CorsLayer::permissive():

  • crates/lance-context-server/src/main.rs:78
  • crates/lance-context-master/src/main.rs:70

That sends Access-Control-Allow-Origin: * with any method and any header. Since neither service has authentication, it actively instructs browsers to allow cross-origin requests from any page on the internet to endpoints that delete stores, trigger compaction, and mutate training data. It converts "unauthenticated on a trusted network" into "reachable from any tab the operator has open".

Why nothing needs it

  • Production: the master serves its own SPA via fallback_service(ServeDir) (main.rs:58-59), and the UI calls a relative base — const API = "/api/v1" (ui/src/api.ts:118). Same-origin, no preflight.
  • Development: vite.config.ts proxies /api to the master process, so the browser still only ever talks to the vite origin. Same-origin again.
  • Data-plane server: has no browser client at all.

Change

Remove the layer from both binaries, drop the now-unused imports, and remove the cors feature from both tower-http dependencies. The workspace builds clean without it, which confirms nothing else was relying on the feature.

A deployment that genuinely needs cross-origin access should opt in with an explicit origin allow-list rather than inheriting a wildcard by default.

Testing

cargo test -p lance-context-server -p lance-context-master → 51 + 12 passed, 0 failed. fmt + clippy clean across the workspace.

Not a functional change for any supported deployment: every current client path is same-origin.

🤖 Generated with Claude Code

Both binaries wrapped their routers in `CorsLayer::permissive()`, which
sends `Access-Control-Allow-Origin: *` and allows any method and header.
Combined with the absence of authentication, that instructs every browser to
permit cross-origin calls from any page on the internet to endpoints that
delete stores and mutate training data.

Nothing needs it. The master serves its SPA itself (`fallback_service`) and
the UI fetches a relative `/api/v1`, so admin traffic is same-origin in
production; in development the vite proxy forwards `/api` to the master, so
it is same-origin there too. No preflight is involved on either path. The
data-plane server has no browser client at all.

Drops the now-unused `cors` feature from both `tower-http` dependencies; the
workspace builds clean, which confirms nothing else relied on it.

A deployment that genuinely needs cross-origin access should opt in with an
explicit allow-list of origins rather than a blanket wildcard.

Co-Authored-By: Claude <noreply@anthropic.com>
@beinan
beinan merged commit d71b195 into main Jul 25, 2026
9 checks passed
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