CORS headers are explicitly configured
Why it matters
Wildcard CORS (Access-Control-Allow-Origin: *) allows any website on the internet to make authenticated API requests using the user's credentials. An attacker's page can silently read your API responses, trigger state-changing calls, and exfiltrate data — all without the user knowing. The impact depends on what your API does: for a read-only public API, wildcard CORS may be intentional; for an API that returns user data or modifies state, it is a critical data exposure. CWE-942 (Permissive Cross-domain Policy with Untrusted Domains) and OWASP A05 (Security Misconfiguration) directly apply. CWE-346 (Origin Validation Error) maps to the failure to validate the requesting origin.
Severity rationale
Info because wildcard CORS becomes dangerous only when the API also handles authentication or returns user-specific data — context determines actual severity.
Remediation
Replace wildcard * CORS with an explicit allowlist of your own domains. Never use * on routes that handle authentication or return user-specific data.
// Next.js API route — src/app/api/example/route.ts
const allowedOrigins = ['https://yoursite.com', 'https://app.yoursite.com']
export async function GET(req: Request) {
const origin = req.headers.get('origin') ?? ''
const headers: Record<string, string> = {}
if (allowedOrigins.includes(origin)) {
headers['Access-Control-Allow-Origin'] = origin
}
return Response.json({ data }, { headers })
}
If your API is genuinely public with no user data, document the intentional wildcard in a comment so auditors can verify it's a conscious decision.
Detection
-
ID:
cors-configured -
Severity:
info -
What to look for: Count all API route files in the project. For each, check for CORS configuration —
Access-Control-Allow-Originheaders set directly or via middleware. Check for wildcard*usage in production config. Report: "X API routes found, Y set CORS headers." -
Pass criteria: Two distinct pass states:
- (a) Same-origin only: No CORS headers are set anywhere in the project — the API is same-origin only and this is correct. 0 routes set cross-origin headers. Detail should note:
"No CORS headers configured — same-origin API usage.". - (b) Explicit allowlist: CORS headers are set with an explicit origin allowlist (not wildcard
*). No more than 0 routes should use wildcard*origin. Detail should note the configured origins.
- (a) Same-origin only: No CORS headers are set anywhere in the project — the API is same-origin only and this is correct. 0 routes set cross-origin headers. Detail should note:
-
Fail criteria:
Access-Control-Allow-Origin: *is set on at least 1 route in production, even if other routes have specific origins configured. -
Skip (N/A) when: No API routes detected — the project has no endpoints that would need CORS configuration.
-
Detail on fail:
"API routes return Access-Control-Allow-Origin: * — any website can make requests to your API"or"CORS middleware uses wildcard origin in production config" -
Remediation: Wildcard CORS (
Access-Control-Allow-Origin: *) allows any website to make API requests to your backend. Restrict it to your own domains:// Example for Next.js API routes const allowedOrigins = ['https://yoursite.com', 'https://app.yoursite.com'] const origin = req.headers.get('origin') if (allowedOrigins.includes(origin)) { res.headers.set('Access-Control-Allow-Origin', origin) }
External references
- cwe · CWE-942 — Permissive Cross-domain Policy with Untrusted Domains
- cwe · CWE-346 — Origin Validation Error
- owasp:2021 · A05 — Security Misconfiguration
Taxons
History
- 2026-04-17·v1.0.0·Initial import from security-headers·automated