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.