When CORS settings change, check that credentialed requests name explicit origins, that the server compares Origin to a fixed allow list instead of echoing it back, and that Vary: Origin is set. Also remember CORS is a browser rule, not server side access control.
What MDN documents
The MDN CORS guide says Access-Control-Allow-Origin with a wildcard allows any origin, but only for requests without credentials. Credentialed requests, for example fetch with credentials set to include, need an explicit origin and a response with Access-Control-Allow-Credentials set to true. With a wildcard and credentials the browser blocks the response.
When a server returns a specific origin instead of a wildcard, it should include Vary: Origin so caches know responses differ by requesting origin. The page also describes preflight: non-simple requests, such as custom headers or methods beyond GET, HEAD and POST, trigger an OPTIONS request first.
What to check in a diff
| Change | Reviewer question |
|---|---|
| Origin set to wildcard | Do any endpoints use cookies or other credentials? |
| Code that copies the request Origin into the response | Is it checked against a fixed list first? |
| Allowing the null origin | Why is it needed? |
| New allowed headers or methods | Is each one required? |
| Missing Vary: Origin | Could a cache serve the wrong origin's response? |
The MDN page does not explicitly warn against echoing back whatever Origin arrives. That is general guidance: reflecting arbitrary origins together with credentials lets any website read authenticated responses, so compare against an allow list.
// red flag: any site can read credentialed responses
res.set("Access-Control-Allow-Origin", req.headers.origin);
res.set("Access-Control-Allow-Credentials", "true");
// safer: only listed origins are echoed
const allowed = new Set(["https://app.example.com"]);
if (allowed.has(req.headers.origin)) {
res.set("Access-Control-Allow-Origin", req.headers.origin);
res.set("Vary", "Origin");
}
What CORS does not do
MDN states CORS is not server side access control. It is a browser mechanism that relaxes the same-origin policy for scripts reading responses. Simple requests still reach your server even when the browser blocks the response, so servers must defend against CSRF, because HTML forms can send simple requests cross-origin. And command line clients ignore CORS entirely, so authentication and authorization still have to be enforced on the server.
A common review mistake is to approve a permissive CORS setting because "the endpoint needs login anyway". If it uses cookies, a permissive setting is exactly what makes login state useful to another site.
Steps for a review
- Read the full set of CORS headers the change produces, not only the origin.
- Trace how the allowed origin is chosen.
- Check which routes the middleware applies to. A global setting touches internal and admin routes too.
- Ask for a test with a disallowed origin that confirms no allow header comes back.
- Check related CSRF protection on state changing routes.
Where Safeguard fits
Safeguard scans dependencies and SBOMs for the frameworks and middleware you use. Try the free scan at gold.safeguard.sh/scan.
Quick check
Can I use a wildcard origin with cookies?
No. Credentialed requests need an explicit origin, and the browser blocks a wildcard response in that case.
Does CORS stop other clients from calling my API?
No. It governs browsers. Other clients ignore it, so enforce authentication and authorization on the server.
Sources
Last reviewed: 19 October 2026.