CORS MISCONFIGURATION CHECKER

Paste a URL. The scanner replays your endpoints with hostile Origin headers and reads what comes back. If your API reflects any origin and allows credentials, any website on the internet can read your users' data.

TEST YOUR CORS POLICY NOW

Enter your URL — we send preflight and simple requests from attacker-controlled origins and grade every Access-Control-* header your server returns.

What is a CORS misconfiguration?

Browsers block one website from reading another website’s responses. CORS is the opt-out: a set of Access-Control-* response headers by which your server tells the browser “this other origin is allowed to read me.” A misconfiguration is any policy that hands that permission to origins you do not control.

The dangerous shape is specific. If your server both (a) allows an attacker-chosen origin and (b) sends Access-Control-Allow-Credentials: true, then any page your logged-in user visits can call your API with their session attached and read the JSON back. No XSS, no phishing page, no stolen password — just a fetch call in a script tag on an unrelated site.

This scanner replays your endpoints with hostile origins so you see the response headers an attacker would see.

Why this happens in AI-generated apps

AI coding tools — Lovable, Bolt, v0, Cursor, Replit — hit the CORS wall early. The first cross-origin fetch fails in the browser console, the model is asked to fix it, and the fastest fix that makes the error disappear is the broadest one: Access-Control-Allow-Origin: *, or origin: true in the Express cors middleware, or an edge function that copies req.headers.origin straight into the response.

Then credentials get added later. * stops working the moment cookies are involved, because browsers refuse that pair — so the next “fix” is to reflect the incoming origin instead. That change silences the error and quietly turns the policy into “every website is trusted.”

Local development hides all of it. On localhost everything is same-origin or already allowlisted, so nothing looks wrong until the app is deployed with real sessions. See CORS and credentials misconfiguration for the full pattern and OWASP Top 10 for AI-generated code for how it sits alongside the other failure modes.

What the scanner checks

WILDCARD ORIGIN

Access-Control-Allow-Origin: * on endpoints that return user-specific or authenticated data.

REFLECTED ORIGIN

Server echoes back whatever Origin was sent — functionally a wildcard, but credential-compatible.

CREDENTIALS + PERMISSIVE

Allow-Credentials: true paired with a reflected, null, or unvalidated origin. The critical combination.

NULL ORIGIN ACCEPTED

Origin: null allowed — reachable from sandboxed iframes and data: URLs an attacker controls.

WEAK DOMAIN MATCH

Prefix or suffix matching that accepts yoursite.com.attacker.tld or notyoursite.com.

BROAD METHODS / HEADERS

Allow-Methods including DELETE and PUT, or Allow-Headers: *, where the app only ever sends GET and POST.

MISSING VARY: ORIGIN

Per-origin policies without Vary: Origin — a CDN can cache one origin's allow header and serve it to everyone.

PREFLIGHT DRIFT

The OPTIONS response allows more than the actual GET/POST response does, usually because a proxy answers preflights separately.

How it works

  1. Discover — we load your URL in a headless browser and collect the API endpoints the frontend actually calls.
  2. Replay — each endpoint is re-requested with hostile Origin values: unrelated domain, null, subdomain, and lookalike.
  3. Preflight — an OPTIONS request is sent for each to capture Allow-Methods, Allow-Headers, and Max-Age.
  4. Grade — every response is scored Pass / Warn / Fail, with the exact header values returned and a paste-ready fix.

Which CORS responses are safe?

Response Safe? Why
Allow-Origin: *, no credentials, public data Yes Browsers refuse to attach cookies; nothing private is readable.
Allow-Origin: * with Allow-Credentials: true No Browsers reject the pair, so the app usually gets “fixed” into reflection next.
Reflected Origin, no credentials Warn No session data leaks, but it defeats any IP or origin-based trust and often precedes a credentials change.
Reflected Origin with Allow-Credentials: true No Any website can read authenticated responses as the logged-in user.
Allow-Origin: null No Sandboxed iframes and data: documents send Origin: null. An attacker can produce one.
Exact-match allowlist with credentials Yes The intended pattern — compare with equality against a fixed list.
Suffix match (endsWith('yoursite.com')) No notyoursite.com passes. Anchor the comparison.
Allow-Headers: * Warn Widens what a cross-origin request may set, including headers your auth layer may trust.
Per-origin policy without Vary: Origin No A shared cache can serve one origin’s allow header to a different origin.

Common fixes

  • Replace reflection with a static array of exact origin strings and compare with ===. If the origin is not in the list, send no Access-Control-Allow-Origin header at all rather than a fallback.
  • Set Access-Control-Allow-Credentials: true only on the endpoints that genuinely need cookies, and never with a wildcard or a reflected origin.
  • Reject Origin: null explicitly. There is almost never a legitimate reason to allow it.
  • Trim Access-Control-Allow-Methods and Access-Control-Allow-Headers to exactly what the frontend sends. GET, POST and a named Content-Type, Authorization list beats *.
  • Always send Vary: Origin when the policy differs per origin, so CDNs and proxies key their cache correctly.
  • Remember CORS is not authorization. It controls who may read a response; it never stops the request from arriving. Keep server-side authorization checks on every endpoint regardless.
  • Re-scan after each deploy — CORS config drifts every time someone debugs a cross-origin error.

COMMON QUESTIONS

01
What is a CORS misconfiguration?
CORS (Cross-Origin Resource Sharing) is the browser rule that decides which websites may read responses from your server. A misconfiguration is any policy that grants that permission too broadly — a wildcard origin, an origin echoed back without validation, or a sloppy domain match that an attacker-registered domain satisfies.
Q&A
02
Why is reflecting the Origin header dangerous?
Reflecting means your server copies whatever Origin the request carried into Access-Control-Allow-Origin. That is equivalent to allowing every origin, while also being compatible with Access-Control-Allow-Credentials: true. Any page the victim visits can then issue authenticated requests to your API with the victim's cookies and read the response body.
Q&A
03
Is Access-Control-Allow-Origin '*' always bad?
No. A wildcard on genuinely public, unauthenticated data — a status endpoint, a public price list, a static font — is fine, and browsers refuse to pair a wildcard with credentials. It becomes dangerous when the same origin also serves authenticated endpoints, or when a developer later 'fixes' a credentials error by switching from the wildcard to origin reflection.
Q&A
04
Doesn't SameSite cookie protection make CORS attacks impossible?
SameSite=Lax or Strict blocks the cookie from riding along on most cross-site requests, which removes a large part of the risk. But apps that authenticate with a bearer token in a header, that set SameSite=None for a legitimate embed, or that rely on a token in localStorage read by a subdomain, are still exposed. Treat SameSite as defense in depth, not as a CORS fix.
Q&A
05
What does the scanner actually send?
OPTIONS preflight requests and normal GET requests carrying Origin values you do not control: an unrelated domain, a null origin, a subdomain of your host, and a lookalike domain that would pass a naive prefix or suffix match. It records the Access-Control-Allow-Origin, Allow-Credentials, Allow-Methods, Allow-Headers, and Vary headers returned for each.
Q&A
06
Why do the checks include lookalike domains?
Because most broken allowlists are string comparisons. A check for endsWith('example.com') accepts notexample.com. A check for startsWith('https://example.com') accepts https://example.com.attacker.tld. The scanner sends those exact shapes so a passing grade means the match logic is anchored, not just present.
Q&A
07
Is the scan safe to run on production?
Yes. It sends read-only requests with different Origin headers — the same traffic a browser would produce if a user visited another website. No writes, no auth bypass attempts, no stored response bodies.
Q&A
08
How do I fix a CORS finding?
Replace dynamic reflection with a static allowlist of exact origin strings, compared with equality. Only set Access-Control-Allow-Credentials when the endpoint genuinely needs cookies, and never alongside a wildcard. Narrow Allow-Methods and Allow-Headers to what the app uses, and always send Vary: Origin so caches do not serve one origin's policy to another.
Q&A

SCAN THE WHOLE APP, NOT JUST CORS

CORS is one header family. The VibeEval agent probes auth, RLS, tokens, and API behavior on the same URL.

RUN FULL SCAN