CORS Policy Risk Checker
Review CORS response headers for unsafe origin trust and credential use, then catch cache or private-network combinations that need priority fixes.| Priority | Control | Evidence | Next action | Copy |
|---|---|---|---|---|
| {{ row.severity }} | {{ row.signal }} | {{ row.evidence }} | {{ row.action }} |
| Header or context | Observed value | Review signal | Copy |
|---|---|---|---|
| {{ row.label }} | {{ row.value }} | {{ row.signal }} |
Prioritized remediation plan
Apply changes to a test route first, then repeat the browser request with the intended origin and credential mode.
- {{ row.title }}{{ row.action }}{{ row.verify }}
A browser normally prevents a page from reading responses that belong to another origin. Cross-Origin Resource Sharing (CORS) is the HTTP opt-in that relaxes that barrier. The responding server states which origin may read the response, which methods and request headers may pass a preflight check, whether credentials are allowed, and which response headers page code may see.
An origin is the combination of scheme, host, and port. HTTP and HTTPS on the same host are different origins, as are two HTTPS addresses on different ports. Path names are not part of the origin. This exact matching matters because reflecting an unapproved request origin can turn a narrow browser permission into a data-exposure route.
CORS is not authentication, authorization, or protection against cross-site request forgery. It controls whether browser code can read a cross-origin response. A server must still decide who may call the route and what each caller may do. Likewise, a permissive header does not make a private response public to every client, but it can remove a browser safeguard when cookies, HTTP authentication, or bearer tokens are involved.
Risk depends on combinations rather than isolated headers:
- A public, non-credentialed asset can legitimately use
Access-Control-Allow-Origin: *. - A credentialed response needs one explicit allowed origin; the wildcard cannot authorize a credentialed CORS read.
- A response that varies its allowed origin should include
Vary: Originso shared caches do not reuse one origin's policy for another. - State-changing methods, sensitive request headers, exposed token-like response headers, and private-network access deserve stricter origin proof.
A header review is a static triage step. Confidence comes from testing both the preflight and actual response from approved and unapproved origins, then checking authorization and cross-site request protections separately.
How to Use This Tool:
Describe the intended browser relationship before judging the returned headers; the same header can be safe for a public asset and risky for an account API.
- Choose the API exposure profile and Browser credential mode that match the real response and request. Use Unknown when credential behavior has not been verified.
- Enter the observed request origin as one serialized HTTP or HTTPS origin, or the literal
nullif that is what the browser sent. - Select the Approved-origin policy and enter approved origins. Wildcard subdomain patterns match subdomains only; they do not match the parent host.
- Choose the Browser target context, then paste response headers from the same browser exchange. Status lines are accepted, but response bodies and console messages are not header evidence.
- Set the Preflight max-age review limit and decide whether origin-specific responses require Cache variance. The limit is your review threshold, not a browser-standard maximum.
- Read the risk band and highest-severity finding, then work through the Fix plan. Retest the same request after each change so one correction does not broaden another permission.
Interpreting Results:
The highest-severity finding identifies the first issue to investigate. The overall risk band combines all findings, so several Medium signals can raise the total even when no single Critical condition exists. Read the evidence text before acting because the same syntax is judged against the selected origin policy, credential mode, route sensitivity, and network context.
A Low score means no priority signal was found under the supplied assumptions. It does not prove that the live application is safe. Repeat an OPTIONS preflight and the actual request from an approved origin and an unapproved origin, and verify authentication, authorization, and cross-site request protections independently.
Missing CORS headers can be correct when a route should never be read cross-origin. They can also be a functionality fault when cross-origin access is intended. Treat route intent as evidence rather than assuming that more CORS headers are always better.
Technical Details:
The review parses response header names case-insensitively, retains repeated values, normalizes HTTP and HTTPS origins, and compares the observed and returned origins with the selected allowlist policy. Findings are then evaluated in security context rather than as a generic header checklist.
Rule Core
The core decisions are ordered around origin trust, credentials, request scope, cache behavior, header exposure, and private-network access.
| Condition | Finding severity | Reason |
|---|---|---|
* with Access-Control-Allow-Credentials: true | Critical | A credentialed CORS response cannot use the wildcard origin. |
Literal null trusted for a credentialed or sensitive response | Critical | Many opaque or sandboxed contexts can serialize to the null origin. |
| Unapproved request origin reflected by a sensitive or credentialed route | Critical | Reflection lacks allowlist proof. |
Specific origin varies by request but Vary: Origin is absent | High in reflection mode; otherwise Medium | A shared cache may reuse a response under the wrong origin policy. |
| State-changing methods or sensitive request headers with broad or unproven origin trust | High for sensitive contexts; otherwise Medium | The preflight permission is broader than the origin evidence. |
| Sensitive response headers exposed to browser code | High | Session, token, authorization, API-key, and cookie-like names should not be readable through CORS. |
| Private-network grant with broad or unproven origin trust | Critical for a private target; otherwise High | The response may enable a public page to reach a more privileged network context. |
An exact allowed origin must match scheme, host, and effective port. An HTTPS pattern for *.example.com matches a subdomain at the same effective port but not the parent host example.com. Only one returned Access-Control-Allow-Origin value is accepted.
A public wildcard is accepted only when the policy explicitly allows it, credentials are absent, the response is not sensitive, and private-network access is not granted. The max-age finding appears only when the parsed value exceeds the chosen review limit and another Medium-or-higher finding is already active.
Additional rules catch multiple or malformed allowed-origin values, an unexpected CORS grant on a no-CORS route, an explicit origin outside the approved list, a reflected response that differs from the observed origin, contradictory credential settings, missing Authorization permission, and wildcard methods or request headers under weak origin proof. Missing allowed-origin evidence is informational for a no-CORS route or static asset and Low otherwise.
The response-header block is limited to 131,072 characters, the approved-origin list to 32,768 characters, and the preflight review limit to a whole number from 0 through 86,400 seconds. Non-header lines are ignored and counted.
Formula Core
Each finding contributes a transparent weight: Critical 35, High 22, Medium 12, Low 5, and Info 0. The total is capped at 100 risk points.
| Risk band | Score |
|---|---|
| Low | 0 to 19 |
| Moderate | 20 to 39 |
| High | 40 to 64 |
| Critical | 65 to 100 |
These weights and bands form a transparent model created for this checker; they are not values defined by the Fetch Standard, OWASP, or the Private Network Access draft.
Limitations and Privacy Notes:
The header block and policy inputs are evaluated in the browser and are not sent to a checker service. Response headers can still contain cookies, tokens, internal hostnames, and tracing identifiers, so redact secrets before sharing screenshots or copied evidence.
- The review does not make a network request or observe browser behavior. Paste headers from the exact preflight or actual response being assessed.
- It does not test authentication, authorization, cross-site request forgery defenses, application routing, cache configuration, or DNS ownership.
- Private Network Access remains an evolving browser specification. Browser behavior and deployment requirements can change.
- Severity depends on the supplied context. An incorrect exposure profile, credential mode, origin list, or target type can understate or overstate risk.
Worked Examples:
Credentialed account API with a wildcard
A response returns Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true for an account API. That combination produces a Critical credential finding worth 35 points. With no other findings, the numeric band is Moderate even though the highest severity is Critical; the severity must take priority. Replace the wildcard with one server-approved origin, then test from both approved and rejected origins.
References:
- Fetch Standard, WHATWG.
- Testing Cross Origin Resource Sharing, OWASP Web Security Testing Guide.
- Private Network Access, Web Platform Incubator Community Group.
- How to configure CORS headers in Apache, Simplified Guide.
- How to show HTTP response headers with cURL, Simplified Guide.