Express.js CORS Misconfiguration

Medium Risk Configuration Weakness
expresscorscross-originjavascriptweb-securitycsrf

What it is

The Express.js application has improper Cross-Origin Resource Sharing (CORS) configuration that allows unauthorized cross-origin requests. This can lead to data exposure, CSRF attacks, or unauthorized API access from malicious websites.

// Vulnerable: Overly permissive CORS
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Access-Control-Allow-Methods', '*');
  res.header('Access-Control-Allow-Headers', '*');
  next();
});
// Secure: Strict CORS configuration
const cors = require('cors');

const corsOptions = {
  origin: ['https://trusted-domain.com', 'https://app.example.com'],
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  optionsSuccessStatus: 200
};

app.use(cors(corsOptions));

💡 Why This Fix Works

The vulnerable code was updated to address the security issue.

Why it happens

Express.js applications configure CORS with Access-Control-Allow-Origin: * while also setting Access-Control-Allow-Credentials: true. This combination is both invalid (browsers reject it) and insecure, indicating an attempt to allow authenticated cross-origin requests from any domain.

Root causes

Wildcard Origin with Credentials

Express.js applications configure CORS with Access-Control-Allow-Origin: * while also setting Access-Control-Allow-Credentials: true. This combination is both invalid (browsers reject it) and insecure, indicating an attempt to allow authenticated cross-origin requests from any domain.

Unvalidated Universal Origin Access

CORS middleware configured to allow all origins without proper validation, either through wildcard (*) or by dynamically reflecting the request Origin header without checking against an allowlist. This permits any website to make cross-origin requests to the API.

Overly Permissive Header Configuration

CORS policies allow excessive headers in Access-Control-Allow-Headers or expose sensitive headers in Access-Control-Expose-Headers. This can enable attackers to access sensitive data or bypass security controls through custom headers.

Missing Preflight Request Validation

Applications don't properly handle or validate CORS preflight (OPTIONS) requests. Missing or incorrect preflight handling can allow unauthorized cross-origin requests or fail to enforce intended CORS restrictions.

Unrestricted HTTP Method Permissions

CORS configuration allows dangerous HTTP methods like DELETE, PUT, or PATCH in Access-Control-Allow-Methods without proper authorization checks. This enables any website to perform state-changing operations on the API.

Fixes

1

Specify Exact Allowed Origins

Replace wildcard (*) origins with an explicit list of allowed domains in the CORS configuration. Use the 'origin' option with an array of specific URLs (e.g., ['https://app.example.com', 'https://admin.example.com']) to limit cross-origin access to trusted domains only.

2

Implement Dynamic Origin Validation

Configure CORS middleware with a function that validates the request origin against an allowlist before granting access. Check the request's Origin header against approved domains, supporting environment-specific configurations for development, staging, and production.

3

Restrict to Necessary HTTP Methods

Configure Access-Control-Allow-Methods to include only HTTP methods required by your API (typically GET and POST). Avoid allowing PUT, DELETE, PATCH unless absolutely necessary, and ensure proper authentication and authorization for state-changing operations.

4

Configure Secure Credentials Handling

If cookies or authentication headers need to be sent cross-origin, set credentials: true in CORS configuration and specify exact allowed origins (never use * with credentials). Implement proper CSRF protection alongside credential-based CORS.

5

Use Strict CORS Middleware Configuration

Configure the cors npm package or equivalent middleware with restrictive settings. Set preflightContinue: false, optionsSuccessStatus: 204, and maxAge for preflight caching. Review all CORS options to ensure they follow security best practices.

6

Implement Preflight Request Validation

Properly handle OPTIONS requests for CORS preflight by validating the requested method and headers against your CORS policy. Return appropriate Access-Control-* headers only for valid preflight requests, and implement request method and header validation.

Detect This Vulnerability in Your Code

Sourcery automatically identifies express.js cors misconfiguration and many other security issues in your codebase.