Misconfigured CORS
Misconfigured CORS at a glance
Overview
Cross-Origin Resource Sharing (CORS) is a browser security mechanism that controls how web pages from one origin can access resources from another origin. Proper CORS configuration is critical for protecting sensitive data and operations.
Common CORS misconfigurations include using wildcard (*) origins with credentials, reflecting any Origin header without validation, overly permissive allowed methods and headers, missing origin validation against an allowlist, and enabling credentials for public APIs. These misconfigurations allow malicious websites to make authenticated cross-origin requests and steal sensitive user data.
Where it occurs
CORS vulnerabilities occur in API or web server configurations that allow any origin, reflect origins without validation, or enable excessive methods, headers, or credentials.
Impact
CORS misconfigurations enable cross-origin data theft where malicious sites steal user data, authentication bypass through credential inclusion, unauthorized API operations, sensitive information disclosure, and can be combined with CSRF for more severe attacks.
Prevention
Prevent CORS misconfigurations by strictly validating origins against an allowlist, never using wildcards with credentials, limiting allowed methods and headers, enabling credentials only when needed, and testing configurations for leaks.
Examples
Switch tabs to view language/framework variants.
CORS configuration reflects any origin with credentials
Server reflects Origin header allowing cross-origin data theft.
const express = require('express');
const app = express();
app.use((req, res, next) => {
// BUG: Reflects any origin
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
app.get('/user/profile', (req, res) => {
res.json({ email: req.user.email, ssn: req.user.ssn });
});- Line 6: Reflects any origin
Reflecting any origin with credentials allows attackers to steal user data.
const express = require('express');
const app = express();
const ALLOWED_ORIGINS = [
'https://app.example.com',
'https://mobile.example.com'
];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (ALLOWED_ORIGINS.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Credentials', 'true');
}
next();
});
app.get('/user/profile', (req, res) => {
res.json({ email: req.user.email });
});- Line 4: Allowlist of trusted origins
- Line 12: Validate before setting header
Use an allowlist of trusted origins and validate before setting CORS headers.
Engineer Checklist
-
Maintain explicit allowlist of trusted origins
-
Never use Access-Control-Allow-Origin: * with credentials
-
Don't reflect Origin header without validation
-
Only enable Access-Control-Allow-Credentials when required
-
Restrict Access-Control-Allow-Methods to needed methods
-
Be specific with Access-Control-Allow-Headers
-
Validate Origin against allowlist before responding
-
Don't trust null origin (can be triggered by sandboxed iframes)
-
Use CORS libraries with secure defaults
-
Test CORS configuration with different origins
-
Monitor for unexpected cross-origin requests
End-to-End Example
An API reflects any Origin header with credentials enabled, allowing malicious websites to steal user data through authenticated cross-origin requests.
// Vulnerable: Reflects any origin
res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');// Secure: Validate against allowlist
const allowedOrigins = ['https://app.example.com', 'https://app2.example.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}Discovery
Send requests with different Origin headers and observe if they're reflected in Access-Control-Allow-Origin responses.
-
1. Test CORS configuration
httpAction
Send cross-origin request with Origin header
Request
GET https://api.example.com/dataBody:"Origin: https://evil.com"
Response
Status: 200Body:{ "note": "Access-Control-Allow-Origin reflects evil.com" }Artifacts
cors_misconfiguration origin_reflection -
2. Test credentials in CORS
httpAction
Check if credentials allowed with wildcard origin
Request
GET https://api.example.com/userResponse
Status: 200Body:{ "note": "Allow-Credentials: true with Allow-Origin: *" }Artifacts
credential_exposure cors_vulnerability -
3. Test preflight bypass
httpAction
Send simple request without preflight
Request
POST https://api.example.com/actionResponse
Status: 200Body:{ "note": "State-changing operation succeeds from any origin" }Artifacts
preflight_bypass csrf_equivalent
Exploit steps
Attacker hosts a malicious page that makes authenticated cross-origin requests to the vulnerable API, stealing user data through the browser's cookie mechanism.
-
1. Steal user data via CORS
Cross-origin data theft
httpAction
Use misconfigured CORS to read user data from attacker site
Request
GET fetch('https://api.example.com/user', {credentials: 'include'})Response
Status: 200Body:{ "note": "User's private data accessible to attacker's JavaScript" }Artifacts
stolen_user_data session_hijacking -
2. Execute authenticated actions
Cross-origin state change
httpAction
Perform actions as victim user
Request
POST fetch('https://api.example.com/transfer', {method: 'POST', credentials: 'include'})Response
Status: 200Body:{ "note": "Attacker performs actions using victim's session" }Artifacts
unauthorized_action account_compromise -
3. Exfiltrate sensitive API responses
Mass data extraction via CORS
httpAction
Read all accessible endpoints from victim's session
Request
GET malicious-site.com/steal.jsResponse
Status: 200Body:{ "note": "Complete API data exfiltrated to attacker" }Artifacts
api_data_theft privacy_breach
Specific Impact
Malicious websites can steal sensitive user data including personal information, authentication tokens, and perform unauthorized operations on behalf of authenticated users.
Fix
Always validate the Origin header against an explicit allowlist of trusted domains. Never reflect the Origin without validation. Only enable credentials when absolutely necessary and with strict origin restrictions.
Detect This Vulnerability in Your Code
Sourcery automatically identifies misconfigured cors vulnerabilities and many other security issues in your codebase.
Scan Your Code for Free