Cors Wildcard with Api Keys
How Cors Wildcard Manifests in Api Keys
CORS wildcard configurations in API key-based authentication systems create dangerous attack surfaces that many developers overlook. When an API accepts API keys for authentication but configures CORS with wildcard origins ("*"), it allows any website to make authenticated requests to your API using stolen or leaked API keys.
Consider this common vulnerability pattern: An API requires an API key in the Authorization header or as a query parameter, but the CORS configuration permits requests from any origin. An attacker who obtains an API key through various means (database leaks, client-side exposure, GitHub repositories) can host a malicious website that makes authenticated requests to your API on behalf of any visitor.
Here's how this typically manifests in code:
// Vulnerable Express.js API with API keys and wildcard CORS
const express = require('express');
const cors = require('cors');
const app = express();
// Dangerous: allows ANY origin to make requests
app.use(cors({
origin: '*',
credentials: true
}));
app.get('/api/data', (req, res) => {
const apiKey = req.headers.authorization?.replace('Bearer ', '') || req.query.api_key;
if (!apiKey || !validateApiKey(apiKey)) {
return res.status(401).json({ error: 'Invalid API key' });
}
// Process request with valid API key
res.json({ data: 'sensitive information' });
});
app.listen(3000);
The vulnerability becomes critical when combined with API keys because:
- API keys are often long-lived and don't expire quickly
- Keys can be easily extracted from client-side code or network traffic
- Wildcard CORS removes the browser's same-origin policy protection
- Attackers can exfiltrate data through their malicious domains
Another manifestation occurs in serverless functions where developers configure permissive CORS for testing but forget to restrict it in production:
// Vulnerable AWS Lambda function with API keys
exports.handler = async (event) => {
// Dangerous: wildcard CORS in response headers
const response = {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true'
},
body: JSON.stringify({
data: await processRequestWithApiKey(event.headers.Authorization)
})
};
return response;
};
This pattern is particularly dangerous for APIs that process financial transactions, handle healthcare data, or provide administrative functions where API key compromise could lead to significant business impact.
API Keys-Specific Detection
Detecting CORS wildcard vulnerabilities in API key systems requires both automated scanning and manual verification. middleBrick's black-box scanning approach tests the unauthenticated attack surface by attempting to make requests from various origins while providing different API key formats.
middleBrick specifically tests for:
- CORS wildcard origins (*) that accept API key authentication
- Credentials flag being true with wildcard origins
- API key exposure through client-side JavaScript
- Pre-flight request handling with API key authentication
Here's how you can detect these issues using middleBrick:
# Scan an API endpoint that uses API keys
middlebrick scan https://api.example.com/v1/data \
--auth-header "Authorization: Bearer YOUR_API_KEY" \
--test-cors \
--output json > report.json
# In your CI/CD pipeline, fail if CORS issues are detected
middlebrick scan https://api.example.com/v1/data \
--auth-header "Authorization: Bearer $API_KEY" \
--fail-on-severity high
Manual detection techniques include:
// Test with curl for wildcard CORS
curl -X OPTIONS https://api.example.com/v1/data \
-H "Origin: https://malicious-site.com" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: Authorization"
// Check response headers for wildcard origins
// Look for: Access-Control-Allow-Origin: *
Additional detection methods:
- Review API documentation for client-side API key usage examples
- Check for API keys in JavaScript bundle files
- Monitor for API key exposure in error responses
- Verify that API keys are not hardcoded in mobile applications
middleBrick's OpenAPI analysis also cross-references your API specification with runtime findings, identifying endpoints that accept API keys but lack proper CORS restrictions.
API Keys-Specific Remediation
Remediating CORS wildcard vulnerabilities in API key systems requires a defense-in-depth approach. The primary fix is restricting CORS to specific, trusted origins while maintaining proper API key validation.
Here's the secure implementation pattern:
// Secure Express.js API with API keys and restricted CORS
const express = require('express');
const cors = require('cors');
const app = express();
// Define trusted origins for your API
const trustedOrigins = [
'https://your-app.com',
'https://admin.your-app.com',
'https://api.your-app.com'
];
// Configure CORS with whitelist
app.use(cors({
origin: function (origin, callback) {
if (!origin) return callback(null, false);
if (trustedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true
}));
// API key validation middleware
function validateApiKey(req, res, next) {
const apiKey = req.headers.authorization?.replace('Bearer ', '') || req.query.api_key;
if (!apiKey || !verifyApiKey(apiKey)) {
return res.status(401).json({ error: 'Invalid or missing API key' });
}
req.apiKey = apiKey;
next();
}
// Apply middleware to protected routes
app.get('/api/data', validateApiKey, (req, res) => {
// Process request with validated API key
res.json({ data: 'sensitive information' });
});
app.listen(3000);
For serverless implementations, use environment variables for trusted origins:
// Secure AWS Lambda function
const trustedOrigins = process.env.TRUSTED_ORIGINS.split(',');
exports.handler = async (event) => {
const origin = event.headers?.origin;
// Verify origin is trusted
if (!trustedOrigins.includes(origin)) {
return {
statusCode: 403,
body: JSON.stringify({ error: 'CORS not allowed' })
};
}
// Validate API key
const apiKey = event.headers?.authorization?.replace('Bearer ', '');
if (!apiKey || !verifyApiKey(apiKey)) {
return {
statusCode: 401,
body: JSON.stringify({ error: 'Invalid API key' })
};
}
// Process request
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': origin,
'Access-Control-Allow-Credentials': 'true'
},
body: JSON.stringify({ data: 'processed result' })
};
};
Additional remediation strategies:
- Implement API key rotation policies (90-180 day expiration)
- Use short-lived JWT tokens instead of static API keys where possible
- Log all API key usage for anomaly detection
- Implement rate limiting per API key
- Use environment-specific API keys (development vs production)
middleBrick's Pro plan includes continuous monitoring that can alert you when new origins attempt to access your API, helping you maintain your CORS whitelist over time.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |