CORS Configuration Checker
Test how a site responds to cross-origin requests and find out whether its CORS policy is dangerously permissive.
What this CORS checker tests
Same-origin policy is the browser's default: JavaScript on one site cannot read responses from another. CORS is how a server opts out of that default, origin by origin, using Access-Control-* response headers. Getting it right means naming exactly which origins may read which responses; getting it wrong means quietly letting any website do it. This tool sends three deliberately unusual requests and reports exactly what came back for each, so you can see the actual behaviour rather than guess at it from a single header dump.
Reflecting an arbitrary origin
We send a normal GET request with Origin: https://averto-cors-test.example — a domain we made up, which cannot be on any real allowlist. Some servers, instead of checking the incoming Origin against a list, just copy it straight into Access-Control-Allow-Origin. If that made-up origin comes straight back, the server isn't doing an allowlist check at all. On its own that lets any site read non-authenticated responses on a visitor's behalf. Combined with Access-Control-Allow-Credentials: true, it means any website can send a credentialed request — cookies and session included — from a victim's browser and read the authenticated response. That is the single most serious finding this tool can produce, because it effectively removes the origin check that credentialed CORS depends on.
The wildcard, in context
Access-Control-Allow-Origin: * looks similar to a reflected origin but means something different: literally every origin is allowed, not just the one that happened to ask. For a public, unauthenticated API this is fine and normal — we mark it informational rather than flagging it, because crying wolf on a correct configuration trains people to ignore the report. It only becomes a real problem paired with credentials, and browsers already refuse to honour that specific combination — though seeing it still signals a CORS layer that isn't distinguishing public from private responses.
Origin: null
We also send a request with the literal Origin: null. This isn't a made-up edge case — browsers send it from sandboxed iframes (<iframe sandbox>), from pages opened directly as local files, and from some redirect chains. If a server accepts null as a trusted origin, an attacker can trivially construct a page that produces exactly this header, making it one of the easier CORS misconfigurations to actually exploit.
The preflight: methods and headers
For requests that aren't "simple" — a PUT, or one carrying an Authorization header — browsers send an OPTIONS preflight first and only proceed if the server explicitly allows it. We send exactly that: Access-Control-Request-Method: PUT and Access-Control-Request-Headers: authorization, from our made-up origin. If the response allows our fake origin and also lists PUT, DELETE or PATCH in Access-Control-Allow-Methods, that's not just a read exposure — it means state-changing calls are reachable cross-origin too. A wildcard or reflected value in Access-Control-Allow-Headers is what would let a cross-origin caller actually attach an Authorization header to that request in the first place.
No CORS headers at all
Most sites should see this, and it's the pass condition, not a gap: if none of the three probes get any Access-Control-* header back, the browser's default same-origin policy is doing its job untouched. You only need CORS headers at all if you deliberately serve another origin — an API for a separate frontend, a public widget, a partner integration.
A correct, scoped configuration
For an API that legitimately needs to serve one or two specific frontends with credentials:
// pseudocode — check the Origin against a real allowlist server-side
const ALLOWED = ['https://app.example.com', 'https://admin.example.com'];
if (ALLOWED.includes(requestOrigin)) {
Access-Control-Allow-Origin: <the matched origin, not *>
Access-Control-Allow-Credentials: true
Vary: Origin
}The Vary: Origin line matters as much as the check itself — without it, a caching layer can serve one visitor's allowed-origin response to a different visitor whose origin should have been rejected.
How the grade is calculated
Every check starts at 100 and deducts based on severity — a reflected origin with credentials costs far more than a long Access-Control-Max-Age. Scores of 90+ earn an A, 75 a B, 55 a C, 35 a D, and below that an F. Treat the grade as a summary: one critical finding here matters more than several informational ones, so read past the letter.
Frequently asked questions
What is CORS?
Cross-Origin Resource Sharing is the set of response headers that tells a browser which other websites are allowed to read a page's or an API's responses via JavaScript. Without any CORS headers, browsers enforce the same-origin policy: only your own site's pages can read your own site's data.
Why is a permissive CORS policy dangerous?
CORS is an opt-out of the browser's default protection. If a server reflects any Origin it's sent and also allows credentials, any website a logged-in visitor happens to open can silently query your API using their session and read the response. The attacker never touches your server directly — the victim's own browser does it for them.
Is Access-Control-Allow-Origin: * always bad?
No. For a genuinely public, unauthenticated API — open data, a CDN asset, a public widget — a wildcard is the correct, intended configuration and this tool marks it as informational rather than a problem. It only becomes a real issue when it's combined with credentials, which browsers reject anyway, or when the endpoint actually serves private data.
How is this different from a security headers checker?
A security headers checker reads the headers on one ordinary request. This tool actively probes the target with several different Origin values and a preflight request to see how the CORS logic actually behaves — a header dump alone cannot show whether a server reflects arbitrary origins, because that behaviour only shows up when you send one it has never seen.
Does this tool modify anything on the target site?
No. Every probe is a GET or an OPTIONS preflight — the same requests a browser sends automatically before certain cross-origin calls. Nothing is created, changed, or deleted, and no authentication is attempted.
Can I check a site I do not own?
Yes. These are the same requests any browser sends when a page happens to make a cross-origin call to that site — passive and non-destructive. As always, only act on the findings for sites you're responsible for.
My site got a low score but I do not use cookies for this API. Should I worry?
Less, but not zero. Without credentials, a permissive CORS policy mainly enables data scraping and lets other sites piggyback on your API from a visitor's browser rather than their own server — useful for abuse, and occasionally a stepping stone to a bigger issue. Tightening the allowlist is still worthwhile even when nothing credentialed is exposed today.