Interlace ESLint
ESLint Interlace
Secure CodingRules

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

AspectDetails
CWE ReferenceCWE-346 (Origin Validation Error)
SeverityHigh (security vulnerability)
Auto-Fix✅ Yes (suggests origin validation)
CategorySecurity
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForAll 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

IssueImpactSolution
🔒 SecurityUnauthorized cross-origin requestsValidate origin whitelist
🐛 Data TheftMalicious sites can access your APIOrigin validation
🔐 CSRF AttacksCross-site request forgery enabledProper CORS configuration
📊 ComplianceViolates security best practicesAlways 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

OptionTypeDefaultDescription
allowInTestsbooleanfalseAllow missing CORS checks in test files
trustedLibrariesstring[]['cors', '@koa/cors', 'express-cors']Trusted CORS libraries to recognize
ignorePatternsstring[][]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 internally

Mitigation: Apply rule to wrapper implementations.

Dynamic Invocation

Why: Dynamic calls not analyzed.

// ❌ NOT DETECTED - Dynamic
obj[method](userInput);

Mitigation: Avoid dynamic method invocation.

Resources

On this page