Regex Dos in Feathersjs with Api Keys
Regex Dos in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability
A Regex DoS (ReDoS) in a Feathers.js service that uses API keys can occur when input validation on API key parameters or related headers relies on regular expressions with exponential backtracking. In Feathers, services are typically defined with a service path and a schema; if you use a custom hook or a before hook to validate an API key against a pattern that includes nested quantifiers or ambiguous groupings, an attacker can supply a crafted string that causes the regex engine to consume excessive CPU time.
For example, consider a Feathers hook that validates an API key against a pattern intended to enforce a specific format such as ^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}$. If the pattern is implemented naively or composed with additional permissive segments, it may be vulnerable to inputs that cause catastrophic backtracking. An attacker can probe the endpoint with specially constructed API key values, inducing high CPU utilization on the server without necessarily triggering rate limits that are applied after authentication. This becomes a practical denial-of-service vector for unauthenticated or lightly authenticated endpoints where API keys are checked via regex rather than via a constant-time lookup (e.g., a hash map or database index).
When combined with the broader attack surface of Feathers services that expose multiple methods (GET, POST, etc.), a vulnerable regex in one service can affect overall system responsiveness. Because Feathers encourages chaining hooks, a poorly designed validation in an authentication hook can cascade into downstream service calls, amplifying resource consumption. The risk is especially pronounced when API keys are accepted both as query parameters and headers; inconsistent validation across these input vectors can create redundant regex checks that compound the performance impact.
In the context of middleBrick’s checks, this scenario maps to the Input Validation and Authentication categories. The scanner tests for patterns that may lead to excessive backtracking by analyzing regex constructs in validation logic and by probing with payloads designed to trigger long-running evaluations. Since middleBrick tests the unauthenticated attack surface, it can highlight endpoints where API key validation logic may be exploited without requiring credentials.
Api Keys-Specific Remediation in Feathersjs — concrete code fixes
To mitigate Regex DoS risks for API key validation in Feathers.js, avoid using complex regular expressions for format validation when simpler checks suffice. Prefer exact length checks, character class validation via simple loops, or built-in string methods. If regex is necessary, ensure patterns are atomic, avoid nested quantifiers, and use non-capturing groups with possessive quantifiers or explicit bounds where supported by the regex engine. Below are concrete examples of safe API key handling in Feathers services.
Example 1: Constant-time lookup with a precomputed set
Store valid API keys in a Set or a hashed lookup structure and validate using strict equality. This avoids regex entirely and provides predictable performance.
// Before: vulnerable regex in a before hook
// hooks/validate-key.js
module.exports = function () {
return function (context) {
const { apikey } = context.params.query;
const unsafePattern = /^[A-Z0-9]{8}-([A-Z0-9]{4}){3,5}$/; // risky
if (!unsafePattern.test(apikey)) {
throw new Error('Invalid API key format');
}
return context;
};
};
// After: constant-time validation using a Set
// hooks/validate-key-safe.js
const validKeys = new Set([
'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
'0123456789abcdef0123456789abcdef'
]);
module.exports = function () {
return function (context) {
const { apikey } = context.params.query;
if (!apikey || !validKeys.has(apikey)) {
throw new Error('Invalid API key');
}
return context;
};
};
Example 2: Simple format validation without backtracking pitfalls
If you must use regex, keep it simple and anchored, and avoid repetition that can cause exponential backtracking. Use exact length segments and avoid nested quantifiers.
// Safe regex pattern for a UUID-like key without catastrophic backtracking
const safePattern = /^[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}$/i;
module.exports = function () {
return function (context) {
const { apikey } = context.params.query;
if (!safePattern.test(apikey)) {
throw new Error('Invalid API key format');
}
return context;
};
};
Example 3: Centralized validation across services
Define a reusable validation function and apply it consistently across services to avoid ad-hoc regex implementations that may vary in safety.
// utils/validate-api-key.js
function validateApiKey(key) {
if (typeof key !== 'string' || key.length !== 36) return false;
// Basic UUID format without complex regex backtracking
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(key);
}
// In a Feathers before hook
module.exports = function () {
return function (context) {
const { apikey } = context.params.query;
if (!validateApiKey(apikey)) {
throw new Error('Invalid API key');
}
return context;
};
};
Additionally, prefer header-based transmission for API keys when possible, and ensure that validation logic is applied uniformly across all input sources. middleBrick’s scans can help identify endpoints where regex-based validation may present irregular patterns by correlating OpenAPI specs with runtime tests, giving you visibility into where remediation is most needed.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |