CORS is explicitly configured (not relying on framework defaults)
Why it matters
Calling app.use(cors()) with no origin: option silently defaults to Access-Control-Allow-Origin: *, which allows any third-party domain to make cross-origin requests to your API and read the responses. OWASP A05 (Security Misconfiguration) and CWE-942 (Permissive Cross-domain Policy) both call this out. When combined with credentials: true, wildcard CORS causes browsers to reject the response anyway — but misconfigured CORS without credentials still exposes unauthenticated API responses to attacker-controlled sites.
Severity rationale
Medium because wildcard CORS exposes unauthenticated API responses to any origin, enabling data exfiltration from endpoints that rely on same-origin as a defense.
Remediation
Always pass an explicit origin list to the CORS configuration. Never rely on the default wildcard.
import cors from 'cors'
app.use(cors({
origin: [
'https://example.com',
'https://app.example.com',
process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : null,
].filter(Boolean),
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
}))
For Next.js, set Access-Control-Allow-Origin headers explicitly in next.config.js using the headers() function with per-path rules rather than installing the cors npm package.
Detection
-
ID:
cors-explicitly-configured -
Severity:
medium -
What to look for: When
cors,@fastify/cors,@koa/cors,next-connect-cors, or similar CORS libraries are inpackage.jsondependencies, walk source files for the import — at least 1 import required for this check to apply. Count all imports and verify a corresponding.use(cors(,app.register(fastifyCors, orcors({...})call exists with an explicitorigin:option (not relying on the default*). EXCLUDE Next.jsnext.config.jsheaders()configurations that explicitly setAccess-Control-Allow-Originheaders. -
Pass criteria: When a CORS library is imported, it is invoked AND the invocation passes an explicit
origin:option that is NOT'*'. Report: "CORS library: [name] imported AND configured with explicit origin: [value]." -
Fail criteria: A CORS library is imported AND either (a) never invoked, OR (b) invoked with
origin: '*'or noorigin:option (which defaults to*). -
Skip (N/A) when: No CORS library in dependencies AND no Access-Control headers configured in
next.config.*/vercel.json/netlify.toml. -
Detail on fail:
"cors imported in src/server.ts AND applied as app.use(cors()) without an origin option — defaults to allowing all origins" -
Remediation: Default CORS allows any origin to call your API, defeating same-origin protection. Always specify allowed origins explicitly:
// Bad: wildcard CORS app.use(cors()) // origin defaults to '*' // Good: explicit allowed origins app.use(cors({ origin: ['https://example.com', 'https://app.example.com'], credentials: true, }))
External references
- cwe · CWE-942 — Permissive Cross-domain Policy with Untrusted Domains
- owasp:2021 · A05 — Security Misconfiguration
- owasp:2021 · A01 — Broken Access Control
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ai-slop-security-theater·automated