Integrity Failures in Feathersjs with Hmac Signatures
Integrity Failures in Feathersjs with Hmac Signatures — how this specific combination creates or exposes the vulnerability
FeathersJS is a framework for real-time web applications that often exposes service endpoints over HTTP and can integrate HMAC signatures to verify message integrity and origin. An integrity failure occurs when the HMAC verification is incomplete, misconfigured, or bypassed, allowing an attacker to tamper with request payloads or query parameters without detection.
Consider a typical HMAC scheme where a client sends a timestamp, a signature, and the payload. If FeathersJS validates the signature but does not enforce freshness checks or does not bind the signature to the full request context (method, path, body, and headers), an attacker can replay a valid signed request or modify non-signature parts of the request. This maps to common OWASP API Top 10 risks such as lack of integrity checks and improper authentication/authorization.
During a black-box scan, middleBrick runs checks for BOLA/IDOR and BFLA/Privilege Escalation alongside integrity-related tests. If the HMAC verification only covers a subset of parameters or uses a weak algorithm, the scan can identify missing validation on critical endpoints. For example, an endpoint that accepts a JSON body with an id and performs an update without ensuring the signed envelope covers the id allows an attacker to change the resource identifier while keeping a valid signature.
Real CVE patterns relevant to this class of issues include cases where signature verification does not include the full request URI and query string, enabling path manipulation. If the server uses a static or predictable nonce or fails to reject replayed timestamps outside an acceptable window, the integrity guarantee breaks. middleBrick’s LLM/AI Security checks do not apply here, but its inventory and property authorization tests can surface endpoints where HMAC coverage is inconsistent.
An example of a vulnerable FeathersJS service definition that only signs the payload body but ignores method and query parameters:
const crypto = require('crypto');
const app = require('feathers')();
app.use('/messages', {
before: {
create: [verifyHmac]
},
after: {},
error: {},
methods: ['create']
});
function verifyHmac(req, res, next) {
const { timestamp, signature, data } = req.body;
const expected = crypto.createHmac('sha256', 'my-secret')
.update(data)
.digest('hex');
if (signature !== expected) {
throw new Error('Invalid signature');
}
// Missing: timestamp validation, method/uri binding, replay protection
next();
}
In this example, an attacker could replay the same signed data with a different timestamp or target a different endpoint if the service uses the same hook for multiple routes. The scan findings would highlight missing binding of the signature to the request context and absence of replay protection.
Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes
Remediation centers on ensuring the HMAC covers all inputs that affect server-side behavior, including HTTP method, request path, query parameters, and the request body. You must also enforce timestamp validation to prevent replay attacks and use constant-time comparison to avoid timing attacks.
Below is a concrete, secure example for a FeathersJS service that signs and verifies the full request context:
const crypto = require('crypto');
const app = require('feathers')();
function buildString(method, url, query, body) {
// Deterministic serialization: sort keys for objects
const sorted = body ? JSON.stringify(body) : '';
return [method.toUpperCase(), url, query || '', sorted].join('\n');
}
app.use('/secure', {
before: {
create: [verifyHmac],
update: [verifyHmac],
patch: [verifyHmac],
remove: [verifyHmac]
},
after: {},
error: {},
methods: ['create', 'update', 'patch', 'remove']
});
function verifyHmac(req, res, next) {
const { timestamp, signature, ...payload } = req.body;
const method = req.method;
const url = req.path; // e.g., '/secure'
const query = req.url.split('?')[1] || '';
const dataString = buildString(method, url, query, payload);
const expected = crypto.createHmac('sha256', process.env.HMAC_SECRET)
.update(dataString, 'utf8')
.digest('hex');
// Constant-time comparison
if (!crypto.timingSafeEqual(Buffer.from(signature || ''), Buffer.from(expected))) {
const error = new Error('Invalid signature');
error.statusCode = 401;
throw error;
}
// Replay protection: reject timestamps older than 2 minutes
const requestTime = parseInt(timestamp, 10);
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - requestTime) > 120) {
const error = new Error('Request expired');
error.statusCode = 401;
throw error;
}
// Optionally store request identifiers to prevent reuse within the window
next();
}
Key points in this remediation:
- The signature is computed over the HTTP method, the request path, the query string, and the request body, ensuring that changing any of these invalidates the signature.
- Timestamp validation prevents replay attacks; adjust the window to match your tolerance for clock skew.
crypto.timingSafeEqualprevents timing attacks on the signature comparison.- Each FeathersJS method (create, update, patch, remove) explicitly uses the same verification hook so coverage is consistent across the operation types.
When using the middleBrick CLI to validate your configuration, you can run middlebrick scan <url> to check whether integrity failures remain detectable. If you need automated enforcement in development, the GitHub Action can add API security checks to your CI/CD pipeline and fail builds if risk scores exceed your chosen threshold. For teams using AI coding assistants, the MCP Server allows scanning APIs directly from the IDE, helping catch misconfigurations early.