Denial Of Service in Feathersjs with Hmac Signatures
Denial Of Service 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 uses feathers-hmac to sign and verify requests. When Hmac Signatures are used for authentication, certain implementation patterns can introduce a Denial of Service (DoS) risk. The DoS exposure arises because signature verification is computationally intensive when performed repeatedly for large or malformed payloads, and FeathersJS may process unauthenticated or unvalidated requests before rejecting them.
An attacker can exploit this by sending many requests with invalid or borderline-valid Hmac signatures. Each request triggers CPU-costly signature verification and possibly deserialization of the payload. If the server performs expensive operations (e.g., hashing large bodies, verifying nested objects, or resolving $ref in OpenAPI specs before early rejection), this can consume disproportionate resources. In a black-box scan, middleBrick tests for Rate Limiting and Input Validation, which can surface whether the API lacks request-size caps or early signature validation that would mitigate resource exhaustion.
Consider an endpoint that accepts a JSON body and an X-HMAC-Signature header. If the server parses and transforms the body (e.g., deep cloning or schema validation) before verifying the Hmac, an attacker can send oversized or deeply nested JSON, causing high memory and CPU usage. This is especially relevant when combined with features like auto-generated models or dynamic $ref resolution in spec analysis, which may inadvertently encourage heavy pre-processing. A practical example of vulnerable code:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const hmac = require('feathers-hmac');
const app = express(feathers());
app.use('/secure', hmac({
secret: 'super-secret-key',
getPayload: (context) => context.raw || context.body
}));
// Vulnerable: body parsed and transformed before signature verification
app.use('/data', (context) => {
// Simulating heavy transformation before hmac verification in some setups
if (context.data) {
context._transformed = JSON.stringify(context.data);
}
return context;
});
app.use(hmac.authenticate());
app.use('/echo', { create(data, params) { return data; } });
In this pattern, if authentication middleware or service hooks run transformation logic before the Hmac verification step, an attacker can force expensive operations. middleBrick’s checks for Authentication and BFLA/Privilege Escalation can highlight whether endpoints enforce early rejection of unsigned or malformed requests, reducing the DoS surface.
Additionally, if the Hmac secret is stored in environment variables but the application lacks proper input validation on the request path or query parameters, an attacker might trigger repeated secret lookups or logging, adding latency. The 12 security checks run in parallel by middleBrick test for these conditions, including checking whether the unauthenticated attack surface is minimized before costly operations.
Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes
To mitigate DoS risks when using Hmac Signatures in FeathersJS, ensure that signature verification occurs before any expensive body parsing or transformation. Defensive coding patterns and configuration reduce CPU and memory strain under attack.
1. Verify Hmac early, before body processing
Move Hmac verification to the top of the request lifecycle. Use a lightweight middleware that checks the signature before parsing large bodies or running hooks. Example:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const crypto = require('crypto');
const app = express(feathers());
// Early Hmac verification middleware
app.use((req, res, next) => {
const signature = req.get('X-HMAC-Signature');
const payload = req.body || '';
const expected = crypto.createHmac('sha256', process.env.HMAC_SECRET)
.update(typeof payload === 'string' ? payload : JSON.stringify(payload))
.digest('hex');
if (!signature || signature !== expected) {
return res.status(401).json({ message: 'Invalid signature' });
}
next();
});
app.use('/data', { create(data, params) { return data; } });
2. Limit payload size and disable body parsing for unsigned probes
Use Express-level body-parser limits or skip parsing for OPTIONS/health checks. Example with limits:
const bodyParser = require('body-parser');
app.use(bodyParser.json({ limit: '10kb' }));
app.use(bodyParser.raw({ type: 'application/json', limit: '10kb' }));
3. Avoid dynamic $ref resolution and heavy transformations before auth
If your API uses OpenAPI specs with $ref, avoid resolving references on every request in untrusted contexts. middleBrick’s OpenAPI/Swagger analysis resolves $ref definitions, which is helpful for documentation but should not be run on each request in production. Keep spec resolution at build time.
4. Use connection and rate limiting alongside Hmac
Configure rate limiting to cap requests per IP, reducing brute-force or resource exhaustion attempts. Example using express-rate-limit:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 60 * 1000,
max: 100
});
app.use(limiter);
5. Apply middleBrick scans to validate remediation
Run middleBrick scans (via the Web Dashboard, CLI, or GitHub Action) to confirm that Authentication checks pass and that Rate Limiting and Input Validation findings show appropriate protections. The CLI command is:
middlebrick scan https://api.example.com/openapi.json
These steps reduce the DoS surface by ensuring Hmac verification is lightweight, early, and protected by complementary controls.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |