HIGH regex dosexpresshmac signatures

Regex Dos in Express with Hmac Signatures

Regex Dos in Express with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Regular expression denial-of-service (ReDoS) occurs when a regex pattern has overlapping or nested quantifiers and is applied to untrusted input. In Express applications that use HMAC signatures, ReDoS can manifest when signature verification or payload parsing uses non-robust regular expressions on user-controlled data, such as headers, query parameters, or request bodies. The combination is risky because HMAC workflows often require extracting values (e.g., signatures, tokens, or IDs) from strings using regex, and if those patterns are complex or unbounded, an attacker can craft inputs that cause catastrophic backtracking, consuming excessive CPU and leading to denial of service.

Consider an Express route that validates a request signature by extracting a timestamp and signature from a header using a regular expression. If the pattern includes optional groups or nested quantifiers, an attacker can send a long, specially crafted string that forces the regex engine to explore many paths. For example, a pattern like /^sig=([a-f0-9]+)?-ts=([\d]+)?/ can exhibit exponential behavior on certain inputs due to the nested quantifiers on character classes. The runtime impact is amplified because signature verification typically occurs on every request; an unauthenticated attacker can trigger the vulnerable regex without needing credentials, making this an efficient vector for disruption.

In the context of the 12 security checks run by middleBrick, this falls under Input Validation and Authentication. The scanner analyzes whether regex patterns applied to incoming data are susceptible to pathological backtracking, and it flags findings with severity and remediation guidance. Since the scan is unauthenticated, it can surface ReDoS risks in public endpoints that use HMAC signatures for integrity checks. A real-world pattern might involve extracting JWT-like tokens or query parameters with overly permissive quantifiers. The scanner cross-references the OpenAPI specification, if available, with runtime behavior to identify discrepancies, such as a documented parameter that is parsed with a fragile regex in the implementation.

An example of a vulnerable Express route might use req.query.token with a non-robust regex to validate format before processing. An attacker can send a query string like ?token=a*aaa|a*aaa|a*aaa... that causes the regex engine to backtrack extensively. Because the scan tests the unauthenticated attack surface, such issues can be detected without credentials. Remediation focuses on simplifying quantifiers, using atomic groups where supported, or avoiding regex for parsing structured tokens when simpler string operations suffice.

middleBrick’s findings include prioritized guidance, mapping issues to frameworks such as OWASP API Top 10. For ReDoS in HMAC contexts, the guidance recommends reviewing regex patterns, bounding repetitions, and considering constant-time string comparison when feasible. Because middleBrick does not fix or block, it provides actionable remediation steps so developers can adjust the implementation and reduce the risk of denial of service through regex-based attacks.

Hmac Signatures-Specific Remediation in Express — concrete code fixes

To mitigate ReDoS in Express applications that use HMAC signatures, prefer deterministic, linear-time parsing and avoid fragile regex patterns. Use built-in string methods or well-audited libraries for token parsing, and ensure quantifiers are bounded. Below are concrete code examples showing a vulnerable approach and a hardened alternative.

Vulnerable implementation using a complex regex to extract and validate an HMAC signature from headers:

const crypto = require('crypto');
const secret = process.env.HMAC_SECRET;

app.get('/data', (req, res) => {
const header = req.headers['x-signature'];
// Vulnerable regex with nested quantifiers and optional groups
const match = header?.match(/^sig=([a-f0-9]+)?-ts=([\d]+)?/);
if (!match) {
return res.status(400).send('Invalid signature format');
}
const [, sig, ts] = match;
const expected = crypto.createHmac('sha256', secret).update(ts).digest('hex');
if (sig !== expected) {
return res.status(401).send('Invalid signature');
}
res.json({ timestamp: ts, data: 'ok' });
});

This pattern risks ReDoS due to the optional groups and character classes that can cause backtracking on malicious input.

Hardened implementation using bounded parsing and avoiding vulnerable regex:

const crypto = require('crypto');
const secret = process.env.HMAC_SECRET;

app.get('/data', (req, res) => {
const header = req.headers['x-signature'];
if (!header || !header.startsWith('sig=')) {
return res.status(400).send('Missing or invalid signature header');
}
// Use bounded parsing instead of complex regex
const parts = header.slice(4).split('-ts=');
if (parts.length !== 2) {
return res.status(400).send('Invalid signature format');
}
const sig = parts[0];
const ts = parts[1];
// Basic format checks to avoid processing malformed input
if (!/^[a-f0-9]{64}$/.test(sig) || !/^\d{1,10}$/.test(ts)) {
return res.status(400).send('Invalid signature format');
}
const expected = crypto.createHmac('sha256', secret).update(ts).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).send('Invalid signature');
}
res.json({ timestamp: ts, data: 'ok' });
});

This approach eliminates nested quantifiers, uses split for extraction, applies bounded patterns for validation, and employs crypto.timingSafeEqual to prevent timing attacks. It reduces the attack surface and avoids the conditions that typically trigger ReDoS.

Additional recommendations include scanning regex patterns with static analysis tools, keeping dependencies updated, and using the middleBrick CLI to verify that changes do not introduce new input validation issues. The CLI can be run with middlebrick scan <url> to assess the endpoint’s behavior against common classes of vulnerabilities, including regex-related risks.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

How can I detect ReDoS risks in HMAC signature parsing in my Express API?
Use the middleBrick CLI to scan your endpoint: run middlebrick scan <url>. The scanner checks Input Validation and Authentication checks and reports findings with severity and remediation guidance, including regex-related risks, without requiring authentication.
What are best practices for writing regex in Express to avoid ReDoS when handling signatures?
Avoid nested quantifiers and unbounded optional groups; prefer bounded repetitions and atomic patterns where supported. Consider using string methods (e.g., startsWith, split, substring) instead of complex regex for parsing structured tokens like HMAC signatures.