Blog · CORS · Updated 2026-08-20

CORS misconfiguration in AI-generated code

Ask Cursor, Bolt, or Lovable to "add CORS support" and the code you get back almost always opens your API to every origin on the internet. Here is why, and the exact moment it stops being harmless.

Usually fine

Wildcard CORS on a public, read-only endpoint that returns the same response to everyone and never uses cookies or an Authorization header. There is nothing to steal that a direct request couldn't already get.

Actually dangerous

A wildcard (or reflected) origin on an endpoint that returns authenticated, per-user data using cookies or credentials. Any site you visit can now read that data as you, silently, in the background.

Why AI coding tools default to this

When an AI coding assistant scaffolds a backend, its goal is a working demo, fast. The moment a browser throws a CORS error during testing, the fastest fix — and the one every AI assistant reaches for — is calling the CORS middleware with no arguments at all, which allows every origin. It is not a bug in the sense of broken code; it is a working default that was never meant to reach production unmodified.

The escalation pattern

The more dangerous version usually arrives in a second step. A developer adds cookie-based auth, hits a new CORS error because credentialed requests need an explicit origin (browsers reject a literal wildcard combined with credentials), and pastes that error back into the assistant. The common fix an assistant produces is to set credentials: true and reflect whatever origin the browser sent — which satisfies the browser's rule while producing the exact same exposure as a wildcard, now with session cookies attached. That specific combination is tracked as CWE-942.

How to check if you're affected

Send a request to each of your API's authenticated endpoints with an Origin header set to some domain you don't own, and inspect the response. Two signs of exposure: Access-Control-Allow-Origin comes back as * or exactly matches whatever you sent (a reflection), and Access-Control-Allow-Credentials is present and set to true on the same response.

The fix

Replace the wildcard or reflection with an explicit allowlist, sourced from an environment variable so it differs cleanly between local, staging, and production:

// Explicit allowlist, not a wildcard or reflection
const ALLOWED_ORIGINS = (process.env.ALLOWED_ORIGINS ?? "").split(",");

function corsHeaders(origin: string | null) {
  if (!origin || !ALLOWED_ORIGINS.includes(origin)) return {};
  return {
    "Access-Control-Allow-Origin": origin,
    "Access-Control-Allow-Credentials": "true",
    "Vary": "Origin",
  };
}

Reject the request outright (not silently allow it) when the origin isn't in the list, and never let Access-Control-Allow-Credentials: true ship on any response that also carries a wildcard or reflected origin.

Not sure which of your endpoints are exposed?

StackSecured tests every reachable endpoint on your live app with real cross-origin requests and flags exactly which ones return Access-Control-Allow-Credentials on a wildcard or reflected origin.

Run a free scan

Common questions

Is wildcard CORS actually exploitable, or just a warning?

+

Depends what the endpoint does. Access-Control-Allow-Origin: * on a public, read-only endpoint with no cookies or tokens is mostly harmless — anyone could get that data by requesting it directly anyway. It becomes a real vulnerability the moment the endpoint returns authenticated, per-user data and relies on cookies or credentials for that authentication, because then any website you visit can silently make that request on your behalf and read the response.

What's the difference between wildcard CORS and wildcard CORS with credentials?

+

A plain wildcard just means any origin can make the request. Combined with Access-Control-Allow-Credentials: true, it means any origin can make an authenticated request using the victim's existing session cookie — this specific combination is tracked as CWE-942 and is what turns an open API into a cross-site data theft vector. Browsers actually block the combination of a literal wildcard with credentials: true in most cases, which is why the more dangerous real-world pattern is an origin that reflects whatever Origin header the browser sends, which has the same effect as a wildcard but passes the credentials check.

Does this affect Next.js API routes the same way as Express?

+

Yes — the vulnerability is about what headers your server sends back, not which framework sends them. A Next.js route handler that sets Access-Control-Allow-Origin: "*" (or reflects the request Origin) on an authenticated route has the identical exposure to an Express app using cors() with no options.

How common is this in AI-generated code?

+

Common enough to be a default, not an edge case. When you ask an AI coding assistant to "add CORS support," the generated code almost always calls the CORS middleware with no arguments — which is equivalent to a wildcard — because that is what makes a demo work immediately without the assistant knowing your actual list of allowed frontend domains.

More reading: JWT and session security mistakes · Vibe-coding security statistics 2026 · Full vibe-coding security checklist