Cors Wildcard in Express with Bearer Tokens
Cors Wildcard in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability
In Express, configuring CORS with a wildcard origin (origin: '*') while using Bearer token authentication creates a critical exposure because the wildcard allows any domain to make authenticated requests on behalf of a user. When credentials or tokens are involved, browsers enforce a stricter CORS policy, and a wildcard origin is not permitted if the request includes credentials such as an Authorization header containing a Bearer token. This mismatch leads to requests being blocked by the browser, but in non-browser clients or misconfigured API consumers, the server may still accept and process these requests as valid, effectively bypassing intended origin restrictions.
Consider an Express setup where CORS is applied globally with * and the server expects a Bearer token in the Authorization header. An attacker-controlled site or a compromised subdomain can send requests with a valid token (if leaked or reused) and the server will honor them because the route does not validate the origin. This is particularly dangerous when tokens are issued broadly or when token binding is not enforced. The vulnerability is not a flaw in Bearer tokens themselves, but in the permissive CORS configuration that allows any origin to present a valid token to protected endpoints.
OpenAPI specifications might describe Bearer security schemes, but if runtime CORS behavior is overly permissive, the documented authentication mechanism does not translate into effective access control. During a scan, such misconfigurations are flagged under Authentication and Property Authorization checks because the server fails to enforce origin constraints on authenticated requests. This can lead to unauthorized cross-origin access to user-specific resources, escalating the impact of token leakage or client-side compromise.
Real-world patterns include using cors middleware with origin: '*' and expecting the browser to block unauthorized origins when Authorization headers are present. Browsers will block the response from being read, but preflight requests may still succeed, giving an attacker insight into the endpoint and potentially enabling token replay in non-browser contexts. Complementary checks such as BOLA/IDOR and Input Validation are relevant because exposed endpoints may also leak identifiers or accept malformed inputs when CORS rules are not aligned with authentication requirements.
For example, an Express route that validates the presence of a Bearer token but does not verify the request origin can be exploited if the token is obtained via cross-site scripting or leakage in logs. The server-side code must correlate the allowed origins with the expected audience of the token, ensuring that permissive settings are never applied to endpoints that validate credentials.
Bearer Tokens-Specific Remediation in Express — concrete code fixes
To secure Express APIs that use Bearer tokens, CORS configuration must explicitly define allowed origins and conditionally apply credentials. Avoid global wildcard origins when Authentication headers are present. Instead, specify an allowlist of trusted origins and set the credentials option to true only when necessary. This ensures that browsers enforce same-origin policies for authenticated requests and reduces the attack surface for token misuse.
Below are concrete, syntactically correct Express examples demonstrating secure CORS setups with Bearer tokens.
Secure CORS with explicit origin allowlist
const cors = require('cors');
const express = require('express');
const app = express();
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
const corsOptions = {
origin: function (origin, callback) {
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
};
app.use(cors(corsOptions));
app.get('/api/profile', (req, res) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Validate token and fetch user data
res.json({ user: 'alice' });
});
app.listen(3000, () => console.log('Server running on port 3000'));
Restricting credentials when using wildcard-like patterns
const cors = require('cors');
const express = require('express');
const app = express();
// Do not use credentials with wildcard origin
app.use(cors({
origin: '*',
credentials: false,
}));
app.get('/api/public', (req, res) => {
res.json({ message: 'Public endpoint, no auth required' });
});
app.get('/api/secure', (req, res) => {
const authHeader = req.headers['authorization'];
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing Bearer token' });
}
// Proceed with token validation
res.json({ message: 'Secure data' });
});
app.listen(3000, () => console.log('Server running on port 3000'));
In both examples, the server does not rely on the browser to enforce security; it validates the Authorization header on every request. For production, integrate token validation using libraries that verify signatures and check scopes. Complementary security practices include rotating secrets, using short-lived tokens, and monitoring for anomalous cross-origin requests, which can be surfaced in continuous monitoring dashboards offered by platforms such as the middleBrick Web Dashboard.
When integrating into CI/CD, the middleBrick GitHub Action can be configured with a threshold to fail builds if risky CORS or authentication configurations are detected in OpenAPI specs or runtime scans. For developers working in AI-assisted environments, the middleBrick MCP Server enables scanning APIs directly from the IDE, helping catch misconfigurations before deployment.
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 |