CORS Misconfiguration
ID |
cors_misconfiguration |
Severity |
high (wildcard + credentials) / low (wildcard alone) |
Remediation Complexity |
trivial |
Remediation Risk |
high |
Remediation Effort |
low |
Family |
API8:2023 - Security Misconfiguration |
CWE |
CWE-942, CWE-346 |
Resource |
configuration |
Language |
Java, JS/TS, Python (Flask + Django), C#, Go, PHP / Laravel |
Description
Detects insecure Cross-Origin Resource Sharing (CORS) configurations across Java / Spring, JS/TS, Python (Flask + Django), C# / ASP.NET, Go, and PHP / Laravel.
Severity is tiered:
-
HIGH — wildcard origin (
*ornull) combined with credentials allowed (Access-Control-Allow-Credentials: true) — directly exploitable. -
LOW — wildcard origin alone (advisory).
Rationale
CORS is the browser-enforced gate that decides whether a script running on https://evil.example can read responses from https://api.yourapp. A correctly tightened CORS policy is the difference between a phished user’s session being a visit to a malicious page and being a full account takeover from that page.
The dangerous combination is Access-Control-Allow-Origin: together with Access-Control-Allow-Credentials: true. Browsers will reject that pair, *unless the server reflects the request’s Origin header back as the response’s allow-origin — which is what most "fix it later" CORS implementations do. Once that’s the wire shape, any origin can read authenticated responses, and any session cookie or Authorization header sent by the browser will be honoured cross-origin.
LOW-tier wildcard alone (no credentials) still lets any origin issue unauthenticated cross-origin requests; rarely a direct vulnerability but always a defence-in-depth loss.
Remediation
-
Never use
with credentials.* If your endpoint needs credentials (cookies,Authorizationheader, client certificates), it must echo a specific origin, validated against an allowlist. -
Don’t reflect the
Originheader. Reflecting unconditionally is equivalent to*+ credentials. -
Allow-list explicit origins. For Spring,
CorsConfiguration.setAllowedOrigins(List.of("https://app.example.com")). For Express,cors({origin: ['https://app.example.com'], credentials: true}). For ASP.NET,WithOrigins("https://app.example.com").AllowCredentials(). -
Limit exposed headers (
Access-Control-Expose-Headers) to what the SPA actually reads. -
Set a sensible
Access-Control-Max-Age(e.g. 3600) so preflight checks are not skipped en masse. -
Use a vetted CORS library with secure defaults rather than hand-rolled response-header logic.
Configuration
The detector recognises a built-in set of dangerous origin values (*, null) and the framework-specific annotations / middleware names that configure CORS. Both lists can be extended via the dangerousOrigins and corsAnnotations properties.
Unless your project uses bespoke CORS plumbing, you typically do not need to configure this detector.
References
-
OWASP API Security Top 10 (2023) - API8:2023 - Security Misconfiguration.
-
CWE-942 : Permissive Cross-domain Policy with Untrusted Domains.
-
CWE-346 : Origin Validation Error.
-
OWASP Cheat Sheets Series: HTML5 Security — Cross-Origin Resource Sharing.
-
MDN — Cross-Origin Resource Sharing (CORS) : authoritative reference for headers and preflight semantics.
-
PortSwigger Web Security Academy — CORS : practical exploit walk-through.