CORS Policy Risk Checker
Check CORS response headers against origin trust, credentials, caching, exposed headers, and private-network access with scored fixes.| Field | Value | Signal | Copy |
|---|---|---|---|
| {{ row.field }} | {{ row.value }} | {{ row.signal }} |
| Control | Selection | Validation effect | Risk effect | Copy |
|---|---|---|---|---|
| {{ row.control }} | {{ row.selection }} | {{ row.validation }} | {{ row.risk }} |
| Severity | Signal | Evidence | Recommendation | Copy |
|---|---|---|---|---|
| {{ row.severityLabel }} | {{ row.signal }} | {{ row.evidence }} | {{ row.recommendation }} |
A browser can send a request to another origin, but page JavaScript cannot read the response unless the response headers allow it. Cross-Origin Resource Sharing, or CORS, is the browser-read permission system that decides which page origins may inspect a cross-origin response and which request conditions are allowed.
An origin is the scheme, host, and port that define a browser security boundary. A secure app domain, an admin subdomain, a local development port, and an HTTP version of the same host are different origins. That exactness is useful for security, but it also means a small configuration shortcut can turn a narrow browser-read grant into a broad one.
The risk is not the presence of CORS by itself. A public font, static asset, or anonymous read-only feed may intentionally be readable by many origins. A credentialed account API, partner API, admin route, device UI, or private-network target needs a much tighter answer because the browser request may carry cookies, HTTP authentication, client certificates, authorization headers, or user-specific authority.
| Situation | Why it changes the review |
|---|---|
| Public static resource | Broad anonymous reads may be fine, but credential grants and readable secret headers should still be absent. |
| Account or admin API | Browser reads should be limited to exact approved origins because responses may contain private or privileged data. |
| Reflected origin response | Echoing the incoming origin is safe only when the server first proves that origin against a maintained allowlist. |
| Local or intranet target | Private Network Access headers need careful origin proof because a less-trusted page may reach a more-private network area. |
CORS does not authenticate a user, authorize a route, prevent every Cross-Site Request Forgery attempt, or block server-to-server access. It answers a narrower browser question: after a request happens, should page JavaScript be allowed to read the response under the selected origin, credential, cache, and network assumptions?
How to Use This Tool:
Review one endpoint, one observed request origin, and one response header sample at a time. Mixing a production route label with test headers or a different browser origin can make the score less useful.
- Enter an
Endpoint labelthat identifies the route, service, environment, or application tier being reviewed. - Choose the
API exposure profileandBrowser credential mode. Use a credentialed, authorization, partner, or admin setting when browser requests may involve cookies, HTTP auth, client certificates, authorization headers, privileged data, or user data. - Paste the
Observed request Origin. Usenullonly when the browser request actually sent the literal null origin value. - Set
Approved-origin policy modeand list trustedApproved origins, one per line. Exact allowlist mode ignores wildcard patterns, while wildcard-subdomain and reflected modes can evaluate controlled subdomain patterns. - Select the
Browser/private-network targetbefore judging private-network access. Intranet, localhost, router, device, and administrative targets should not be treated like ordinary public web traffic. - Paste only response headers from DevTools, a proxy capture,
curl -i, or an OPTIONS preflight. If the input review reports ignored lines, remove request headers, response bodies, console errors, or lines without colons. - Open
Advancedwhen cache timing matters. KeepVary: Originrequired for reflected or per-origin responses, and lower the preflight max-age review limit when stale browser preflight decisions would slow incident cleanup.
Start with the summary and Risk Register, then compare Header Snapshot and Access Mode Matrix. Use CORS Exposure Map to see which categories contributed to the score, and use JSON when you need a structured copy of the assessment.
Interpreting Results:
The highest-severity row usually deserves attention before the total score. Findings such as Wildcard origin with credentials, Unapproved origin reflected, Sensitive headers exposed, or Private Network Access allowed broadly identify the header decision that should be reviewed first.
| Visible cue | Best first reading | What to verify next |
|---|---|---|
| ACAO * with ACAC true | A wildcard read grant is paired with credential sharing. | Return one approved origin for credentialed browser routes, and keep public wildcard CORS separate from account data. |
| Origin unproven | The observed origin was not confirmed against the approved-origin list. | Correct the allowlist if it is incomplete, or stop reflecting that origin if it is not trusted. |
| Vary: Origin missing | A specific readable origin appears without the cache variance signal expected by the selected review mode. | Add Vary: Origin when the returned origin can differ by request origin, especially behind shared caches or CDNs. |
| Sensitive request headers accepted broadly | Authorization-like request headers are allowed while origin trust is broad or unproven. | Allow sensitive request headers only for approved browser origins that actually need them. |
| No baseline CORS risk signal | The pasted headers did not trigger scored findings under the selected assumptions. | Still confirm server-side allowlists, route authorization, CSRF protections where relevant, and the actual browser response. |
A low score is not a security approval. It means the visible headers and selected assumptions did not match the checked risk patterns. False confidence is most likely when the wrong credential mode is selected, the approved-origin list is stale, or the copied headers came from a different response than the one the browser used.
Technical Details:
A CORS read decision begins with the request Origin and the response's access-control headers. Access-Control-Allow-Origin names the origin that may read the response, uses * for public non-credentialed reads, or uses the special null value. Sensitive routes should compare the request origin with a server-side allowlist and return one approved origin only when it matches.
Credentialed access narrows the safe choices. A response that permits credentials should not rely on a public wildcard origin. Authorization-capable preflights deserve similar care because a browser can ask to send headers such as Authorization, X-CSRF-Token, or an API key header before the actual request.
Cache behavior can change who receives a readable response. When the allowed origin changes by request, shared caches need Vary: Origin so an origin-specific response is not reused for another caller. Long preflight caching can also slow emergency fixes when a risky decision has already been accepted by the browser.
Formula Core:
The displayed risk score is a capped sum of finding weights. Informational findings add no score; low, medium, high, and critical findings add progressively larger weights.
S is the displayed score, w is each finding weight, and n is the number of findings. Critical, high, medium, low, and informational findings use weights of 35, 22, 12, 5, and 0. One high finding plus two medium findings gives 22 + 12 + 12 = 46, which lands in the High band.
| Risk band | Score boundary | How the band should be read |
|---|---|---|
| Critical | S >= 65 |
Multiple serious signals, or a critical credential, origin, or private-network combination, needs immediate review. |
| High | 40 <= S < 65 |
Broad origin trust, sensitive headers, state-changing methods, or private access signals are strong enough to block casual approval. |
| Moderate | 20 <= S < 40 |
The policy needs cleanup, confirmation, or a written exception before it becomes a comfortable baseline. |
| Low | S < 20 |
No major checked signal was found, but route intent and server-side policy still need confirmation. |
Rule Core:
| Review area | Scored signal | Technical consequence |
|---|---|---|
| Origin trust | Missing, invalid, repeated, wildcard, null, unapproved, or reflected origin values. |
Browser read access may be absent, ambiguous, broader than intended, or tied to attacker-controlled input. |
| Credentials | Access-Control-Allow-Credentials: true with wildcard or unusable origin evidence. |
Credential-capable responses need one approved origin, not a public origin grant. |
| Methods and request headers | Wildcard methods, state-changing methods, wildcard request headers, or authorization-like request headers with unproven origin trust. | Cross-origin callers may be allowed to send more powerful preflighted requests than intended. |
| Readable response headers | Readable authorization, session, token, API key, cookie, or similar headers. | Page JavaScript can inspect response headers that should not carry reusable secrets. |
| Preflight caching | Access-Control-Max-Age above the selected limit when other meaningful risk already exists. |
Browsers may keep using a risky preflight decision longer than incident cleanup expects. |
| Private-network access | Access-Control-Allow-Private-Network: true with broad or unproven origin trust. |
A less-trusted page may gain browser-mediated access toward a local, private, intranet, router, or device target. |
Header parsing is intentionally narrow. Status lines are skipped, blank lines are ignored, and only name: value lines become evidence. That keeps request bodies, response bodies, console text, and unrelated trace output out of the assessment.
Limitations and Privacy Notes:
The assessment is a static browser-header review performed from the values you paste into the page. It does not send test requests, execute browser fetches, prove which response a CDN serves to another origin, confirm cookies or tokens exist, or inspect server-side authorization. Use the findings to decide what to test next with real browser traffic, server logs, cache behavior, and route-level access checks.
Worked Examples:
Credentialed account API with exact origin
An account route returns Access-Control-Allow-Origin for the approved app origin, Access-Control-Allow-Credentials: true, and Vary: Origin. With browser credentials selected, exact allowlist mode selected, and the same app origin listed as approved, the useful result is a Low score unless another header contradicts the selected access mode.
Wildcard response on a public file
A public static JSON file uses Access-Control-Allow-Origin: * with no credentials, no private-network grant, no authorization request header, and no sensitive exposed headers. Under public wildcard and no-credentials assumptions, the wildcard can remain Low. Reviewing the same header sample as a partner/admin API or authorization-capable browser request raises the score because the route intent no longer matches public read access.
Reflected attacker origin
A test request sends an unapproved origin, and the response reflects that same origin while the approved-origin list contains only the real app and admin origins. In reflected allowlist mode, Risk Register should show Unapproved origin reflected, often with Critical or High severity when credentials or sensitive data are involved. The fix is to reflect only origins that pass the server-side allowlist.
Troubleshooting ignored header lines
A copied terminal trace includes request headers, body text, and lines without colons. The input review reports ignored lines, and Header Snapshot may show missing access-control fields. Recopy only the response headers from the actual response or OPTIONS preflight, then rerun the review so the score is based on real header evidence.
FAQ:
Does CORS stop a request from reaching the server?
Not by itself. CORS controls whether browser JavaScript can read the response, so the server still needs authentication, authorization, CSRF protection where relevant, and route-level validation.
Why is Vary: Origin important?
When a server returns a specific readable origin that can change by request, shared caches need to vary on the request origin. Otherwise one caller can receive a cached response that was prepared for another origin.
Why did a public wildcard become high risk?
The wildcard is only treated as acceptable when the selected context is public, non-credentialed, non-sensitive, and not private-network access. Change those assumptions only when they match the real route.
Can I paste headers from a failed browser request?
Yes, but paste the response headers that the browser received, not console error text. If the input review says lines were ignored, clean the sample before trusting Risk Register.
What should I fix first?
Start with Critical and High Risk Register rows. Credentialed wildcard origins, reflected unapproved origins, sensitive exposed headers, and broad private-network grants should be resolved before lower-risk cache or cleanup notes.
Glossary:
- Origin
- The scheme, host, and port that define a browser security boundary.
- ACAO
- Short for
Access-Control-Allow-Origin, the response header that names the origin allowed to read the response. - ACAC
- Short for
Access-Control-Allow-Credentials, the response header that allows a credentialed browser request to expose the response when other CORS rules also pass. - Preflight
- A browser OPTIONS check used before certain cross-origin requests, especially requests with non-simple methods or headers.
- Reflected origin
- A response that returns the request origin as the allowed origin, which is safe only when the origin was checked first.
- Private Network Access
- A browser protection area for requests from less-private contexts toward local, intranet, device, or other more-private network targets.
References:
- Fetch Standard, WHATWG.
- Private Network Access, Web Platform Incubator Community Group.
- Cross-Origin Resource Sharing (CORS), MDN Web Docs.
- Testing Cross Origin Resource Sharing, OWASP Web Security Testing Guide.
- How to configure CORS headers in Apache, simplified.guide.
- How to configure CORS headers in Nginx, simplified.guide.
- How to show HTTP response headers with cURL, simplified.guide.