Cors Wildcard in Express with Hmac Signatures
Cors Wildcard in Express with Hmac Signatures — how this specific combination creates or exposes the vulnerability
In Express, enabling a CORS wildcard (origin: true or origin: '*') while also using Hmac Signatures for request authentication can unintentionally weaken origin verification. When the server reflects any incoming Origin header into Access-Control-Allow-Origin and allows credentials or custom headers, the browser’s CORS policy may permit cross-origin requests that bypass intended source restrictions.
Hmac Signatures typically rely on a shared secret to sign a canonical string composed of selected headers, the request path, and the request body. If the server uses the wildcard origin in CORS and also reflects origins in the CORS headers, a malicious site can craft requests that include the required Hmac headers (e.g., x-api-key, x-signature) and have them accepted because the server validates the signature but does not strictly enforce an allowlist of trusted origins.
During scanning, middleBrick’s checks for Authentication, BOLA/IDOR, and Unsafe Consumption can surface this combination as a risk. Even though Hmac Signatures provide integrity, an unrestricted CORS policy can allow unauthorized origins to make authenticated requests, effectively exposing the endpoint to cross-origin abuse. This is especially relevant for endpoints that return sensitive data or perform state-changing actions, as the browser will include cookies or authorization headers when the frontend origin is not explicitly controlled.
For example, an Express route that signs requests with Hmac but sets res.set('Access-Control-Allow-Origin', req.headers.origin) without validating req.headers.origin against an allowlist can be abused. A site under attacker control can send a request with a valid Hmac signature if the shared secret is embedded in client-side code or exposed via subresource leakage, and the browser will honor the response due to the wildcard reflection.
Hmac Signatures-Specific Remediation in Express — concrete code fixes
To mitigate risk, combine strict CORS origin validation with robust Hmac Signature verification in Express. Always use an allowlist of trusted origins instead of reflecting arbitrary origins, and ensure the Hmac verification logic covers all inputs that influence the canonical string.
const crypto = require('crypto');
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
function verifyHmac(req, res, next) {
const signature = req.headers['x-signature'];
const timestamp = req.headers['x-timestamp'];
const apiKey = req.headers['x-api-key'];
if (!signature || !timestamp || !apiKey) {
return res.status(401).json({ error: 'Missing authentication headers' });
}
// Protect against replay attacks by checking timestamp skew
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
return res.status(401).json({ error: 'Request expired' });
}
const secret = process.env.HMAC_SECRET;
const payload = `${timestamp}\n${req.method}\n${req.path}\n${req.body ? JSON.stringify(req.body) : ''}`;
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).json({ error: 'Invalid signature' });
}
next();
}
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.set('Access-Control-Allow-Origin', origin);
res.set('Access-Control-Allow-Credentials', 'true');
res.set('Access-Control-Allow-Headers', 'x-api-key,x-signature,x-timestamp,content-type');
}
next();
});
app.post('/webhook', verifyHmac, (req, res) => {
res.json({ received: true });
});
This approach ensures that only requests from trusted origins are reflected in CORS headers and that the Hmac signature is computed over a canonical representation of the method, path, body, and timestamp. Including a timestamp and checking its skew mitigates replay attacks, which is important when Hmac Signatures are used without TLS session binding in high-risk endpoints.
For production deployments, consider additional hardening such as rotating secrets, binding signatures to IP ranges where feasible, and validating content types to prevent ambiguous parsing. middleBrick’s checks for Authentication and Unsafe Consumption can help verify that your configuration does not inadvertently expose endpoints to cross-origin abuse while still using Hmac Signatures for integrity.
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 |