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.
Medium because wildcard CORS exposes unauthenticated API responses to any origin, enabling data exfiltration from endpoints that rely on same-origin as a defense.
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.
ID: ai-slop-security-theater.unapplied-middleware.cors-explicitly-configured
Severity: medium
What to look for: When cors, @fastify/cors, @koa/cors, next-connect-cors, or similar CORS libraries are in package.json dependencies, 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, or cors({...}) call exists with an explicit origin: option (not relying on the default *). EXCLUDE Next.js next.config.js headers() configurations that explicitly set Access-Control-Allow-Origin headers.
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 no origin: 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,
}))