CORS misconfiguration allowing unauthorized cross-origin access to sensitive APIs

High Risk api-security
corscross-originapicsrfdata-theftmisconfigurationbrowser-security

What it is

APIs with misconfigured Cross-Origin Resource Sharing (CORS) policies allow unauthorized domains to make requests and potentially access sensitive data. Common misconfigurations include wildcard origins with credentials, improper origin reflection, and overly permissive allowed headers and methods, leading to data theft, credential leakage, and cross-site request forgery attacks.

// VULNERABLE: Multiple CORS misconfigurations const express = require('express'); const cors = require('cors'); const app = express(); // PROBLEM 1: Wildcard origin with credentials const dangerousCorsOptions = { origin: '*', // DANGEROUS credentials: true, // ENABLES theft methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['*'] // OVERLY PERMISSIVE }; app.use(cors(dangerousCorsOptions)); // PROBLEM 2: Dynamic origin reflection app.use((req, res, next) => { const origin = req.headers.origin; // VULNERABLE: Reflecting any origin if (origin) { res.header('Access-Control-Allow-Origin', origin); res.header('Access-Control-Allow-Credentials', 'true'); } next(); }); // PROBLEM 3: Weak origin validation app.use((req, res, next) => { const origin = req.headers.origin; // BYPASSABLE: Substring matching if (origin && origin.includes('example.com')) { res.header('Access-Control-Allow-Origin', origin); res.header('Access-Control-Allow-Credentials', 'true'); } next(); }); // Sensitive endpoints exposed app.get('/api/user/profile', (req, res) => { res.json({ email: req.user.email, paymentMethods: req.user.paymentMethods }); }); // Attack: evil.com can steal user data
// SECURE: Strict CORS configuration const express = require('express'); const cors = require('cors'); const app = express(); // Explicit origin whitelist const ALLOWED_ORIGINS = [ 'https://app.example.com', 'https://admin.example.com', 'https://mobile.example.com' ]; // Development origins (non-production only) if (process.env.NODE_ENV !== 'production') { ALLOWED_ORIGINS.push('http://localhost:3000'); } // Secure origin validation function function validateOrigin(origin, callback) { // Allow no origin (mobile apps, server-to-server) if (!origin) { return callback(null, true); } // Strict exact match validation if (ALLOWED_ORIGINS.includes(origin)) { callback(null, true); } else { // Log CORS violation console.warn('CORS violation attempt:', { origin, timestamp: new Date().toISOString() }); callback(new Error('Not allowed by CORS')); } } // Secure CORS configuration const corsOptions = { origin: validateOrigin, credentials: true, // Safe with strict validation methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'], exposedHeaders: ['X-Total-Count'], maxAge: 300, // 5 minutes optionsSuccessStatus: 200 }; app.use(cors(corsOptions)); // Additional security headers app.use((req, res, next) => { res.header('X-Content-Type-Options', 'nosniff'); res.header('X-Frame-Options', 'DENY'); next(); }); // Protected endpoints app.get('/api/user/profile', (req, res) => { res.json({ email: req.user.email, profile: req.user.profile }); });

💡 Why This Fix Works

The vulnerable configurations use wildcard origins, dynamic origin reflection, or weak substring validation, allowing any website to make authenticated requests and steal user data. The secure version implements explicit origin whitelisting with exact matching, validates at both middleware and endpoint levels, logs violations, and never combines wildcard origins with credentials. This prevents cross-origin attacks while maintaining legitimate cross-origin access for authorized domains.

Why it happens

Typical mistakes in app/data layers enable this vulnerability.

Root causes

Fixes

1

2

3

4

5

Detect This Vulnerability in Your Code

Sourcery automatically identifies cors misconfiguration allowing unauthorized cross-origin access to sensitive apis and many other security issues in your codebase.