Replace wildcard CORS with explicit ALLOWED_ORIGINS allowlist#379
Replace wildcard CORS with explicit ALLOWED_ORIGINS allowlist#379advikdivekar wants to merge 1 commit into
Conversation
cors('*') permitted any origin to read API responses, removing the
Same-Origin Policy as a defence layer for all current and future
endpoints with no per-origin review.
Replace with an origin callback that checks against an ALLOWED_ORIGINS
environment variable (comma-separated, defaults to localhost:5173 for
local development). Enable credentials:true so session cookies work
on cross-origin requests from the listed frontend.
Document ALLOWED_ORIGINS in .env.sample so developers set the correct
production domain when deploying.
Closes GitMetricsLab#374
✅ Deploy Preview for github-spy ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What is the problem
backend/server.jsline 15 configuresapp.use(cors('*')). This tells every browser that any origin on the internet is permitted to read API responses, completely removing the Same-Origin Policy as a defence layer.The impact is twofold. First, every unauthenticated endpoint is freely readable from any origin with no review — a page on
evil.comcanfetch()the API and read the full JSON response. Second, every future endpoint added by any contributor is silently exposed by the same wildcard with no per-origin review step, creating a permanently expanding attack surface.What was changed
backend/server.jscors('*').process.env.ALLOWED_ORIGINS(comma-separated string) and splits it into an array of permitted origins, defaulting tohttp://localhost:5173so local development requires no config change.origincallback to thecors()call that allows requests with noOriginheader (server-to-server / health-check calls) and rejects all other origins not on the list with an error.credentials: trueso session cookies are accepted on cross-origin requests from listed origins.GETandPOSTand allowed headers toContent-Type.backend/.env.sampleALLOWED_ORIGINSso developers know to set the correct production domain when deploying.Why this approach
An allowlist driven by an environment variable means dev, staging, and production each declare only their own frontend origin with no code changes between environments. The
!originguard in the callback is necessary to allow server-to-server calls (monitoring, Docker health checks) which browsers never make and therefore carry noOriginheader. Without this guard those calls would be rejected by the CORS middleware even though they pose no cross-origin risk.credentials: trueis required alongside the explicit allowlist — CORS wildcard and credentials cannot coexist in browsers, so enabling credentials is only safe once the wildcard is gone.How to test
http://localhost:5173, the same request must succeed and return a JSON response.Access-Control-Allow-Originresponse header shows the exact requesting origin (e.g.,http://localhost:5173), not*.ALLOWED_ORIGINS=http://localhost:5173,https://myapp.comin the backend.envand confirm both origins are permitted while a third is rejected.Edge cases covered
Originheader (server-to-server, curl without-H) are allowed through without being on the list.ALLOWED_ORIGINSvalue is trimmed after splitting so accidental whitespace around the comma does not silently reject a valid origin.http://localhost:5173means existing local development setups work without any.envchanges.Verification
Labels:
type:securitylevel:intermediategssoc:approvedCloses #374
Please assign this PR to me under GSSoC 2026.