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 (* or null) 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, Authorization header, client certificates), it must echo a specific origin, validated against an allowlist.

  • Don’t reflect the Origin header. 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