Learn · WHATWG Fetch
CORS
How a site lets other websites read its responses, and the settings that quietly give it away.
Browsers enforce the same-origin policy: a script on one site cannot read the response from another. That is what stops a page you visit from reading your webmail in the background. Cross-Origin Resource Sharing is the controlled exception. A server can send headers that tell the browser to allow specific other origins to read its responses. Used properly it is how an API serves a separate front end. Used carelessly it removes the protection it was meant to relax.
The headers
Access-Control-Allow-Origin: https://app.example.com Access-Control-Allow-Credentials: true
- Access-Control-Allow-Origin — which origin may read the response. It takes a single origin or the wildcard *. It cannot list several origins, so servers that support more than one check the request's Origin against a list and echo back the match.
- Access-Control-Allow-Credentials — when true, the other site's script may send the visitor's cookies with the request and read the response. This is the dangerous half, since it lets another site act as the logged-in user.
What goes wrong
- Reflecting any Origin with credentials allowed. Some servers copy the incoming Origin straight into Allow-Origin so everything just works. Combined with Allow-Credentials: true, that lets any website on the internet read the visitor's private data. This is the serious one.
- Allowing the null origin. Sandboxed frames, local files and some redirects send Origin: null, and an attacker can produce one on demand, so allowing it is equivalent to allowing everyone.
- A wildcard with credentials. The specification forbids it and browsers block the response, so it does not leak by itself, but it signals a misconfiguration, and the usual fix is the reflection problem above.
- Loose allow-list matching, such as checking only that the origin ends with example.com, which also matches attackerexample.com.
What a plain wildcard means
Access-Control-Allow-Origin: * without credentials means any site may read the response, but only as an anonymous visitor. That is correct for genuinely public data such as a public API or a font file, and wrong for anything that depends on who is asking. Surface reports a bare wildcard as informational for this reason.
Surface reads the CORS headers on your homepage response, passively. It does not send crafted Origin headers to probe your server, so a clean result describes what the homepage volunteers, not every endpoint of your API.
Is your domain actually covered?
Surface checks CORS — and everything else on this page — against your real DNS and headers, free, in seconds.
Scan your domain →