Integer Overflow in Express with Hmac Signatures
Integer Overflow in Express with Hmac Signatures — how this specific combination creates or exposes the vulnerability
An integer overflow in an Express application that uses Hmac signatures can occur when user-controlled numeric values (e.g., timestamps, counters, or version parameters) are included in the data that is signed. If the application uses a fixed-size integer (such as a 32-bit unsigned integer) to compute or store the value before or during signing, an attacker may supply a large number that causes the integer to wrap around. This can lead to signature validation bypass or an accepted signature that does not match the intended payload.
Consider an endpoint that accepts a timestamp and uses it to build a string-to-sign for an Hmac signature. If the timestamp is parsed as a 32-bit integer and an attacker provides a very large number, the runtime may wrap the integer, producing a different numeric value than expected. If the application then uses this wrapped value to compute the Hmac, the resulting signature may coincidentally match the attacker-supplied signature due to an implementation flaw, or it may expose inconsistencies that can be leveraged in a signature validation bypass. This is particularly dangerous when the signature is used for authorization, such as verifying webhook events or API requests where the integrity of the numeric field is assumed.
In the context of middleBrick’s security checks, this scenario falls under Input Validation and BOLA/IDOR considerations: unchecked large integers may allow an attacker to manipulate the signed data space. The LLM/AI Security checks do not directly test integer overflow, but the scanner’s inventory and input validation tests can surface endpoints that accept numeric identifiers and use Hmac signatures, highlighting where additional validation is required. Real-world attack patterns, such as those seen in CVE-2022-24785 (where signature validation was bypassed via parameter manipulation), align with these classes of flaws when numeric integrity is not enforced.
To detect this class of issue, middleBrick scans unauthenticated attack surfaces and compares runtime behavior against the OpenAPI/Swagger specification, including full $ref resolution. If your spec defines numeric parameters used in signature construction and the runtime accepts values outside expected bounds, the scan can flag the endpoint for review. This does not imply the engine fixes the issue; rather, it provides prioritized findings with severity and remediation guidance so developers can add proper range checks and canonicalization before signing.
Hmac Signatures-Specific Remediation in Express — concrete code fixes
Remediation centers on ensuring integer values are handled with fixed-width, bounds-checked types and that the data used in the Hmac string-to-sign is canonical and validated before signing or verification. Below are concrete Express examples using Node.js built-in crypto.
Example 1: Safe integer handling and Hmac signing
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
const SHARED_SECRET = process.env.HMAC_SECRET;
if (!SHARED_SECRET) {
throw new Error('HMAC_SECRET is required');
}
function validateTimestamp(ts) {
const num = Number(ts);
// Ensure it is a safe integer and within an acceptable window (e.g., ±5 minutes)
if (!Number.isSafeInteger(num)) {
return false;
}
const now = Date.now();
const FIVE_MINUTES = 5 * 60 * 1000;
return Math.abs(now - num) <= FIVE_MINUTES;
}
app.post('/webhook', (req, res) => {
const { timestamp, action, amount } = req.body;
if (!validateTimestamp(timestamp)) {
return res.status(400).json({ error: 'Invalid timestamp' });
}
const payload = `${timestamp}:${action}:${amount}`;
const hmac = crypto.createHmac('sha256', SHARED_SECRET).update(payload).digest('hex');
// Expect signature in header or body
const receivedSignature = req.headers['x-signature'] || req.body.signature;
const expectedSignature = crypto.createHmac('sha256', SHARED_SECRET).update(payload).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(expectedSignature))) {
return res.status(401).json({ error: 'Invalid signature' });
}
res.json({ status: 'ok' });
});
app.listen(3000, () => console.log('Server running on port 3000'));
Example 2: Express middleware that verifies Hmac signatures with integer checks
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
const SHARED_SECRET = process.env.HMAC_SECRET;
function verifyHmac(req, res, next) {
const { timestamp, ...data } = req.body;
const ts = Number(timestamp);
// Reject non-safe integers and out-of-window timestamps
if (!Number.isSafeInteger(ts) || Math.abs(Date.now() - ts) > 5 * 60 * 1000) {
return res.status(400).json({ error: 'Invalid timestamp' });
}
const keys = Object.keys(data).sort();
const canonical = keys.map((k) => `${k}:${data[k]}`).join('|');
const payload = `${timestamp}|${canonical}`;
const expected = crypto.createHmac('sha256', SHARED_SECRET).update(payload).digest('hex');
const received = req.headers['x-signature'];
if (!received || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
return res.status(401).json({ error: 'Invalid signature' });
}
next();
}
app.post('/api/action', verifyHmac, (req, res) => {
res.json({ received: req.body });
});
app.listen(3000, () => console.log('Server running on port 3000'));
Recommendations summary
- Use Number.isSafeInteger to validate numeric inputs before including them in the string-to-sign.
- Define an acceptable time window for timestamps to prevent replay and overflow-related confusion.
- Use canonical parameter ordering and include all relevant fields used in the signature to avoid ambiguity.
- Use crypto.timingSafeEqual for signature comparison to avoid timing attacks.
- Leverage middleBrick’s CLI to scan endpoints that accept numeric identifiers and employ Hmac signatures; the CLI can be integrated into scripts with JSON output for automation.
- For CI/CD, the GitHub Action can enforce a minimum security score and fail builds if findings related to input validation or signature handling appear.