Skip to content
SEO Optimizer is live, Audit on page SEO and AI-search readiness. Try it free
Connexion

How to Fix CORS Misconfiguration

Cross-Origin Resource Sharing (CORS) is the mechanism that lets a browser decide whether JavaScript running on one origin can read a response from another. Get it too loose and you've handed any website on the internet a way to read data meant only for your own app.

New to CORS? Read CORS explained for web developers for how the same-origin policy and preflight requests work. This guide is the practical fix.

The Misconfiguration Scanverra Flags Most

The single most dangerous CORS mistake is sending both of these headers on the same response:

response headersThe combination browsers explicitly forbid - but plenty of servers still send it
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Modern browsers are supposed to refuse to expose the response when both are present, but Scanverra flags it as a critical finding regardless - some HTTP client libraries and older browser versions don't enforce that refusal consistently, and a server sending this pairing at all indicates the CORS policy wasn't actually designed, just switched on to make an error go away.

One step down in severity: Access-Control-Allow-Origin: * on its own, without credentials. If the endpoint returns anything user-specific or sensitive - even without cookies, maybe via a query-string token - a wildcard still lets any site's script read it.

How This Usually Happens

  • Copy-pasted from a Stack Overflow answer. Access-Control-Allow-Origin: * is the fastest way to make a CORS error disappear during development, and it often just stays in production.
  • A framework default nobody revisited. Some API scaffolding tools enable permissive CORS out of the box for local development convenience.
  • Reflecting the Origin header to "support everyone". Dynamically echoing back whatever Origin the browser sent, instead of checking it against an allowlist, achieves the same exposure as a wildcard while looking more deliberate in the response.

How to Fix It

1. Maintain an explicit allowlist

Validate the incoming Origin against a known list, and only echo it back if it matches:

server (Node/Express example)Explicit allowlist instead of a wildcard or blind reflection
const ALLOWED_ORIGINS = ["https://app.example.com", "https://staging.example.com"];

app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (origin && ALLOWED_ORIGINS.includes(origin)) {
    res.setHeader("Access-Control-Allow-Origin", origin);
    res.setHeader("Vary", "Origin");
  }
  next();
});

2. Only set Allow-Credentials when you mean it

If the endpoint doesn't need cookies or HTTP auth sent cross-origin, don't set Access-Control-Allow-Credentials at all. If it does, it must be paired with a specific origin from step 1 - never a wildcard.

3. Scope CORS per-route, not globally

A public, read-only endpoint and an authenticated account API rarely need the same policy. Most frameworks let you apply CORS middleware selectively rather than one blanket rule for the whole app - see our API security basics guide for the broader pattern.

4. Don't forget preflight (OPTIONS) requests

Non-simple requests (custom headers, methods other than GET/POST) trigger a preflight OPTIONS request first - make sure your allowlist logic runs there too, not just on the actual request.

How Scanverra Detects This

Scanverra's security scan inspects the actual Access-Control-Allow-Origin and Access-Control-Allow-Credentials response headers on your site and flags the wildcard-plus-credentials combination as critical, and a bare wildcard on a non-public endpoint as medium severity - the same class of check used across its full header analysis .

FAQ

Questions fréquentes

Not by itself - a wildcard on a genuinely public, unauthenticated endpoint (a public API returning non-sensitive data) is fine. It becomes critical the moment it's paired with Access-Control-Allow-Credentials: true, because browsers are supposed to reject that combination, and a server that sends both anyway signals a misconfiguration attackers actively look for.

No. CORS is enforced by the browser, not the server - the request still reaches your server either way. What CORS controls is whether the browser lets the calling page's JavaScript read the response. A non-browser client (curl, a script, another server) ignores CORS headers entirely.

Because CORS is a browser-only restriction. curl doesn't send an Origin header or enforce the response, so a missing or misconfigured CORS header only shows up once real page JavaScript tries to fetch() the endpoint from a different origin.

Only if you also never set Allow-Credentials: true. Reflecting the Origin dynamically is functionally identical to a wildcard for any origin that asks - it just looks more specific. If the endpoint touches authenticated data, validate the Origin against an explicit allowlist instead of reflecting it.

Gratuit - aucune inscription requise

Check this on your own site

Run a free scan and see exactly where you stand - no sign-up required.

Lancer l'audit gratuit