Skip to main content
ESLint Interlace
Plugin: lambda-securityRules

no-permissive-cors-response

Detects permissive CORS headers in Lambda API Gateway responses

Keywords: CORS, Lambda, API Gateway, CWE-942, security, Access-Control-Allow-Origin, wildcard, auto-fix

CWE: CWE-942
OWASP Mobile: M8: Security Misconfiguration

Detects permissive CORS headers in Lambda API Gateway responses. This rule is part of eslint-plugin-lambda-security.

⚠️ This rule errors by default in the recommended config.

Quick Summary

AspectDetails
CWE ReferenceCWE-942 (Permissive Cross-domain Policy)
Severity🔴 High
Auto-Fix✅ Yes
CategorySecurity
Best ForLambda functions returning API Gateway responses

Vulnerability and Risk

Vulnerability: Lambda functions that return responses with Access-Control-Allow-Origin: * allow any website to access the API.

Risk: Combined with credentials, attackers can steal authentication tokens or session data from users who visit malicious sites.

Rule Logic Flow

Examples

❌ Incorrect

// Lambda handler with wildcard CORS - VULNERABLE
export const handler = async (event) => {
  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ data: 'sensitive' }),
  };
};

// Also vulnerable in error responses
export const handler = async () => {
  return {
    statusCode: 500,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
    body: JSON.stringify({ error: 'Internal error' }),
  };
};

✅ Correct

// Specific origin - SAFE
export const handler = async (event) => {
  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': 'https://app.example.com',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ data: 'sensitive' }),
  };
};

// Dynamic origin validation - SAFE
const ALLOWED_ORIGINS = [
  'https://app.example.com',
  'https://admin.example.com',
];

export const handler = async (event) => {
  const origin = event.headers?.origin || event.headers?.Origin;
  const allowedOrigin = ALLOWED_ORIGINS.includes(origin)
    ? origin
    : ALLOWED_ORIGINS[0];

  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': allowedOrigin,
      Vary: 'Origin',
    },
    body: JSON.stringify({ data: 'sensitive' }),
  };
};

Options

OptionTypeDefaultDescription
allowInTestsbooleanfalseAllow permissive CORS in test files
{
  "rules": {
    "lambda-security/no-permissive-cors-response": "error"
  }
}

Best Practices

1. Use Environment Variable for Origin

const ALLOWED_ORIGIN = process.env.CORS_ORIGIN || 'https://app.example.com';

return {
  statusCode: 200,
  headers: {
    'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
  },
  body: JSON.stringify(data),
};

2. Add Vary Header for Dynamic Origins

headers: {
  'Access-Control-Allow-Origin': validatedOrigin,
  'Vary': 'Origin'  // Important for caching
}

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Headers from Variable

Why: Headers stored in variables are not analyzed.

// ❌ NOT DETECTED - Headers from variable
const headers = { 'Access-Control-Allow-Origin': '*' };
return { statusCode: 200, headers, body: '...' };

Mitigation: Use inline headers. Validate config at startup.

Headers from Spread

Why: Spread hides actual header values.

// ❌ NOT DETECTED - Headers spread
const baseHeaders = getBaseHeaders(); // May include origin: '*'
return { statusCode: 200, headers: { ...baseHeaders }, body: '...' };

Mitigation: Explicitly define CORS headers inline.

Response Factory Functions

Why: Response helpers are not recognized.

// ❌ NOT DETECTED - Response factory
function createResponse(body) {
  return {
    statusCode: 200,
    headers: { 'Access-Control-Allow-Origin': '*' }, // Hidden
    body: JSON.stringify(body),
  };
}
export const handler = async () => createResponse({ data: 'test' });

Mitigation: Apply rule to response helper modules.

API Gateway Configuration

Why: CORS configured at API Gateway level is not visible.

// ❌ NOT DETECTED (correctly) - API Gateway handles CORS
// serverless.yml or SAM template has CORS: '*'
return { statusCode: 200, body: '...' };

Mitigation: Review API Gateway CORS configuration separately.

Resources

Error Message Format

The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:

🔒 CWE-942 OWASP:A01 CVSS:7.5 | CORS Misconfiguration detected | HIGH
   Fix: Review and apply the recommended fix | https://owasp.org/Top10/A01_2021/

Message Components

ComponentPurposeExample
Risk StandardsSecurity benchmarksCWE-942 OWASP:A01 CVSS:7.5
Issue DescriptionSpecific vulnerabilityCORS Misconfiguration detected
Severity & ComplianceImpact assessmentHIGH
Fix InstructionActionable remediationFollow the remediation steps below
Technical TruthOfficial referenceOWASP Top 10

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.