Too-broad CORS Policy

ID

csharp.too_broad_cors_policy

Severity

critical

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

low

Resource

Misconfiguration

Language

CSharp

Tags

ASVS50:v3.4.2, CWE:942, NIST.SP.800-53, OWASP:2025:A02, PCI-DSS:6.5.10

Description

An ASP.NET Core CORS ('Cross-Origin Resource Sharing') policy is configured to allow requests from any origin while also allowing credentials. The CorsPolicyBuilder chain combines AllowAnyOrigin() (or an origin predicate SetIsOriginAllowed(_ ⇒ true) that accepts every origin) with AllowCredentials(). Using WithOrigins("*") is equally over-broad.

Rationale

CORS relaxes the browser’s same-origin policy so that a page served from one origin can read responses from another. Allowing every origin to send credentialed requests (cookies, HTTP authentication, or client TLS certificates) means any website a victim visits can invoke authenticated endpoints on this application on the victim’s behalf and read the responses.

This combination is so dangerous that the CORS specification forbids it: a compliant browser rejects a response whose Access-Control-Allow-Origin is * when credentials are included. Frameworks work around this by reflecting the caller’s origin back in the header, which effectively turns "any origin" into "the attacker’s origin" and defeats the protection entirely. The result is a cross-site data-theft and cross-site request-forgery exposure over any authenticated route.

services.AddCors(o => o.AddPolicy("open", b =>
    b.AllowAnyOrigin()          // VULNERABLE: every origin is allowed
     .AllowCredentials()));     //             together with credentials

// Equivalent over-broad configurations:
policyBuilder.SetIsOriginAllowed(_ => true).AllowCredentials();   // VULNERABLE
builder.WithOrigins("*").AllowAnyHeader().AllowCredentials();     // VULNERABLE

Remediation

Allow only the specific origins that must be trusted, and enable credentials only for that explicit allow-list. Never combine a wildcard / accept-any-origin policy with AllowCredentials().

services.AddCors(o => o.AddPolicy("trusted", b =>
    b.WithOrigins("https://app.example.com", "https://admin.example.com")  // FIXED
     .AllowCredentials()
     .AllowAnyHeader()
     .AllowAnyMethod()));

If the endpoints do not need credentials, drop AllowCredentials(); a wildcard origin is only acceptable for anonymous, non-credentialed requests.