Integer Overflow in Feathersjs with Hmac Signatures
Integer Overflow in Feathersjs with Hmac Signatures — how this specific combination creates or exposes the vulnerability
An integer overflow in a FeathersJS application that uses Hmac Signatures can occur when user-controlled numeric values are used in arithmetic that determines buffer sizes, loop bounds, or signature-length calculations. If an attacker can supply a large or crafted integer that wraps around a fixed-size integer type, the resulting computed length may be far smaller than expected. This mismatch can cause a buffer to be undersized for the provided data, leading to out-of-bounds reads or writes during Hmac generation or verification. Because Hmac Signatures depend on exact byte-level inputs, an overflow can corrupt the computed hash or cause the runtime to compare a truncated signature, inadvertently accepting a malformed or malicious signature.
In FeathersJS services, integer overflow risk is amplified when endpoint parameters (e.g., limit, skip, or pagination-related integers) flow into logic that also handles Hmac Signatures for request integrity or webhook verification. If an unsigned 32-bit integer wraps, the size used to allocate a buffer for the payload or signature may be smaller than the actual data, creating a window where an attacker can supply a payload that bypasses length checks. During verification, the runtime might compute a smaller Hmac digest buffer due to the overflowed size, then compare it against the provided signature. This can lead to incorrect matches or runtime errors that expose internal state, depending on how the framework handles buffer operations and error reporting.
Real-world patterns include using values from query strings or headers to compute Hmac over concatenated parameters. For example, if a service computes an Hmac over userId and a timestamp without validating that these integers remain within safe bounds, an oversized value could trigger an overflow in intermediate calculations. Because FeatherJS allows custom hooks and transport layers, an attacker might target an endpoint that signs requests with Hmac to manipulate the computed length and evade signature validation. This combination of business-logic integers and cryptographic integrity checks means that even a mathematically small overflow can have outsized security implications, such as signature forgery or unexpected application behavior.
Because middleBrick scans the unauthenticated attack surface and tests input validation and data exposure, it can surface risks where integer handling intersects with Hmac Signatures. The scanner does not rely on internal implementation details but observes runtime behavior when submitting crafted integers alongside signed payloads, looking for inconsistencies in signature acceptance or unexpected errors. Developers should ensure that all integers used in buffer sizing or signature-related math are bounded, validated, and processed using safe arithmetic libraries. OWASP API Top 10 categories such as Input Validation and Data Exposure map to these concerns, and findings from a scan can guide targeted remediation and testing.
Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes
To remediate integer overflow risks in FeathersJS when using Hmac Signatures, ensure that all integers influencing buffer sizes or cryptographic operations are validated and constrained before use. Use explicit bounds checks, prefer big integer libraries when necessary, and avoid relying on JavaScript’s implicit number coercion for security-sensitive calculations. Below are concrete code examples that demonstrate safe handling of integers in the context of Hmac Signatures.
Example 1: Safe integer parsing and bounds checking before Hmac computation
const crypto = require('crypto');
function safeHmacSign(payload, secret, timestamp) {
// Validate and clamp timestamp to a safe range
const safeTimestamp = Number.isInteger(timestamp) ? timestamp : parseInt(timestamp, 10);
if (!Number.isSafeInteger(safeTimestamp) || safeTimestamp < 0) {
throw new Error('Invalid timestamp');
}
if (safeTimestamp > Number.MAX_SAFE_INTEGER - 1000) {
throw new Error('Timestamp out of safe range');
}
const hmac = crypto.createHmac('sha256', secret);
hmac.update(Buffer.from(payload, 'utf8'));
hmac.update(Buffer.from(safeTimestamp.toString(), 'utf8'));
return hmac.digest('hex');
}
// Usage in a FeathersJS hook
app.hooks({
before: {
create: [context => {
const { data } = context;
const signature = safeHmacSign(data.message, process.env.HMAC_SECRET, data.timestamp);
context.params.meta = { signature };
return context;
}]
}
});
Example 2: Validating integer parameters used in payload size calculations
function computeBufferSize(items) {
// Ensure items is a safe integer before arithmetic
const count = Number.isInteger(items) ? items : parseInt(items, 10);
if (!Number.isSafeInteger(count) || count < 0 || count > 10000) {
throw new Error('Invalid item count');
}
// Each item is assumed to have a fixed overhead; prevent overflow in multiplication
const overheadPerItem = 64;
if (count > (Number.MAX_SAFE_INTEGER - overheadPerItem) / overheadPerItem) {
throw new Error('Integer overflow risk in buffer size');
}
return count * overheadPerItem;
}
app.service('messages').hooks({
before: {
all: [context => {
const bufferSize = computeBufferSize(context.params.query.limit || 10);
context.params.meta = { bufferSize };
return context;
}]
}
});
Example 3: Using a library for safe arithmetic in signature length checks
const Big = require('big.js');
function verifySignature(payload, receivedSignature, secret, timestamp) {
const base = new Big(timestamp).plus(1000);
const safeBase = base.toNumber();
if (!Number.isSafeInteger(safeBase)) {
throw new Error('Timestamp arithmetic overflow');
}
const expected = safeHmacSign(payload, secret, safeBase);
// Constant-time comparison to avoid timing leaks
const received = receivedSignature || '';
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
}