Free tool
CORS tester
Check a CORS preflight or actual response against the origin, method and headers a browser would send.
Runs entirely in your browser
What this checks
- Access-Control-Allow-Origin against the origin you specify, including wildcards and the literal "null"
- The wildcard-plus-credentials combination, which the CORS specification rejects
- Vary: Origin, so shared caches do not serve one origin's response to another
- Access-Control-Allow-Methods and Access-Control-Allow-Headers against a preflight
- Access-Control-Max-Age, which controls how often the browser re-runs the preflight
- Access-Control-Expose-Headers, which controls what the calling code can read
Your data stays in this tab
This tool runs as JavaScript in your browser. Whatever you paste is read by the page and analysed locally — it is never uploaded, logged or stored, and the tool does not send any request to the API you are inspecting. Close the tab and it is gone.
How the browser decides
CORS is not a server-side permission system. It is a set of instructions the browser follows to decide whether the JavaScript on one origin may read a response from another. The server states its wishes in the response headers; the browser enforces them. That is why a header that looks wrong in isolation can still be correct — the check depends on the origin, the method and the credentials in the request.
The rules the tool applies are the ones that bite most often:
- The origin must match. With credentials, the value of
Access-Control-Allow-Originhas to be the exact origin, character for character. A wildcard is rejected outright whenAccess-Control-Allow-Credentials: trueis also present. - Scheme and port are part of the origin.
https://app.example.comandhttps://app.example.com:8443are different origins, and so arehttp://andhttps://on the same host. - The literal string
nullis an origin. It matches sandboxed iframes,data:URLs and somefile://pages — so it is not the safe choice it often gets mistaken for. - A preflight has to allow the method and headers. The browser sends the real request only if the preflight response permits them.
A worked example
This response is the most common CORS misconfiguration there is — a wildcard origin with credentials turned on:
HTTP/2 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Type: application/jsonThe browser rejects it. The CORS specification does not allowAccess-Control-Allow-Origin: * together withAccess-Control-Allow-Credentials: true, so the response is blocked before the calling code sees it — and the console error the developer sees is a generic CORS failure that does not obviously point at the cause.
The fix is to echo the requesting origin instead of the wildcard, and to tell caches that the response now varies by origin:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: OriginFor a preflight, add the methods and headers the browser is about to ask for:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 600
Vary: OriginQuestions
How do I get the CORS headers?
The simplest way is to open the browser devtools, go to the Network tab, find the request, and read the response headers. For a preflight, look for the OPTIONS request the browser sent just before the real one. You can also run curl with an Origin header: curl -i -H "Origin: https://app.example.com" https://api.example.com/endpoint.
What is the difference between a preflight and an actual request?
A simple GET with no custom headers does not trigger a preflight — the browser sends it directly and checks the response headers. Anything that is not a simple request triggers an OPTIONS preflight first: a non-simple method such as PUT or DELETE, a non-simple header such as Authorization or Content-Type: application/json, or a request that needs credentials. The preflight response has to allow the method and the headers before the real request is sent at all.
Why does a wildcard origin get flagged even when it is valid?
It is valid, and it is reported as a warning rather than a failure for that reason. A wildcard is only correct when the response is the same for every caller. If the response varies by origin — and it almost always does once cookies are involved — the wildcard lets any site read data it should not. The warning exists because that is the most common way CORS gets configured by accident.
Does the tool send the request for me?
No. It reads the response headers you give it and evaluates them against the origin, method and headers you tell it about. It never contacts a host.
What does Vary: Origin have to do with it?
If your response depends on the Origin header, a shared cache — a CDN or a corporate proxy — needs to know that, or it will store one origin's response and hand it to another. Sending Vary: Origin is how you tell the cache to key the entry by origin. Without it, the failure is intermittent and hard to reproduce, because it only shows up for users behind a proxy.
Get EndpointCheck when it launches
We're building automated API security scanning for teams that ship REST APIs. It isn't live yet. Join the waitlist and we'll email you once when it is.