no-missing-cors-check
Detects missing CORS validation (wildcard CORS, missing origin check) that can allow unauthorized cross-origin requests. This rule is part of [`eslint-plugin-se
Keywords: CORS, cross-origin resource sharing, CWE-346, security, ESLint rule, origin validation, wildcard CORS, Access-Control-Allow-Origin, auto-fix, LLM-optimized, code security
Detects missing CORS validation (wildcard CORS, missing origin check) that can allow unauthorized cross-origin requests. This rule is part of eslint-plugin-secure-coding and provides LLM-optimized error messages that AI assistants can automatically fix.
⚠️ This rule warns by default in the recommended config.
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-346 (Origin Validation Error) |
| Severity | High (security vulnerability) |
| Auto-Fix | ✅ Yes (suggests origin validation) |
| Category | Security |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | All web APIs, REST services, microservices with cross-origin requests |
Vulnerability and Risk
Vulnerability: Misconfigured Cross-Origin Resource Sharing (CORS) policies, such as using the wildcard * origin or reflecting the Origin header without validation, allow any website to access the application's resources.
Risk: Attackers can host a malicious website that forces a user's browser to send requests to the vulnerable application. Since the browser includes the user's session cookies (if credentials are allowed), attackers can steal sensitive data or perform unauthorized actions (CSRF/Data Exfiltration).
Rule Details
Missing CORS validation can allow unauthorized websites to make requests to your API, potentially leading to data theft or unauthorized actions. This rule detects wildcard CORS origins (*) and missing origin validation.
Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 🔒 Security | Unauthorized cross-origin requests | Validate origin whitelist |
| 🐛 Data Theft | Malicious sites can access your API | Origin validation |
| 🔐 CSRF Attacks | Cross-site request forgery enabled | Proper CORS configuration |
| 📊 Compliance | Violates security best practices | Always validate origins |
Detection Patterns
The rule detects:
- Wildcard CORS origin:
origin: "*"in CORS configuration - Wildcard CORS header:
Access-Control-Allow-Origin: *in response headers - Missing origin validation: CORS middleware without origin checking
Examples
❌ Incorrect
// Wildcard CORS origin
app.use(
cors({
origin: '*', // ❌ Allows all origins
credentials: true,
}),
);
// Wildcard CORS header
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*'); // ❌ Allows all origins
next();
});
// Missing origin validation
app.use(
cors({
credentials: true, // ❌ No origin specified
}),
);✅ Correct
// Origin validation with whitelist
const allowedOrigins = ['https://example.com', 'https://app.example.com'];
app.use(
cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
}),
);
// Origin validation with array
app.use(
cors({
origin: allowedOrigins, // ✅ Only allows specified origins
credentials: true,
}),
);
// Origin validation in custom middleware
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin); // ✅ Validated
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
next();
});
// Using trusted CORS library
import cors from 'cors';
app.use(
cors({
origin: process.env.ALLOWED_ORIGINS?.split(',') || [],
credentials: true,
}),
);Configuration
{
rules: {
"secure-coding/no-missing-cors-check": ["error", {
allowInTests: false, // Allow in test files
trustedLibraries: ['cors', '@koa/cors', 'express-cors'], // Trusted CORS libraries
ignorePatterns: [] // Additional safe patterns to ignore
}]
}
}Options
| Option | Type | Default | Description |
|---|---|---|---|
allowInTests | boolean | false | Allow missing CORS checks in test files |
trustedLibraries | string[] | ['cors', '@koa/cors', 'express-cors'] | Trusted CORS libraries to recognize |
ignorePatterns | string[] | [] | Additional safe patterns to ignore |
Rule Logic Flow
Best Practices
1. Use Origin Whitelist
// ✅ Good - Validate against whitelist
const allowedOrigins = [
'https://example.com',
'https://app.example.com',
process.env.FRONTEND_URL,
].filter(Boolean);
app.use(
cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
}),
);2. Use Environment Variables for Origins
// ✅ Good - Configure via environment
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [];
app.use(
cors({
origin: allowedOrigins,
credentials: true,
}),
);3. Validate Origin Before Setting Header
// ✅ Good - Validate then set header
app.use((req, res, next) => {
const origin = req.headers.origin;
const allowedOrigins = ['https://example.com'];
if (origin && allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader(
'Access-Control-Allow-Headers',
'Content-Type, Authorization',
);
}
if (req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});4. Use CORS Library with Validation
import cors from 'cors';
// ✅ Good - Use trusted library with validation
app.use(
cors({
origin: (origin, callback) => {
const allowedOrigins = ['https://example.com'];
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
}),
);5. Different Origins for Development and Production
// ✅ Good - Environment-specific origins
const allowedOrigins =
process.env.NODE_ENV === 'production'
? ['https://example.com']
: ['http://localhost:3000', 'http://localhost:3001'];
app.use(
cors({
origin: allowedOrigins,
credentials: true,
}),
);Known False Negatives
The following patterns are not detected due to static analysis limitations:
Values from Variables
Why: Values stored in variables are not traced.
// ❌ NOT DETECTED - Value from variable
const value = userInput;
dangerousOperation(value);Mitigation: Validate all user inputs.
Wrapper Functions
Why: Custom wrappers not recognized.
// ❌ NOT DETECTED - Wrapper
myWrapper(userInput); // Uses dangerous API internallyMitigation: Apply rule to wrapper implementations.
Dynamic Invocation
Why: Dynamic calls not analyzed.
// ❌ NOT DETECTED - Dynamic
obj[method](userInput);Mitigation: Avoid dynamic method invocation.
Related Rules
no-unvalidated-user-input- Detects unvalidated user inputno-unsanitized-html- Detects unsanitized HTML injectionno-unescaped-url-parameter- Detects unescaped URL parametersno-sql-injection- Detects SQL injection vulnerabilities
Resources
no-missing-authentication
Detects missing authentication checks in route handlers. This rule is part of [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure
no-missing-csrf-protection
Detects missing CSRF token validation in POST/PUT/DELETE requests. This rule is part of [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plu