Regex Dos in Feathersjs with Dynamodb
Regex Dos in Feathersjs with Dynamodb — how this specific combination creates or exposes the vulnerability
Regex Denial of Service (Regex DoS) occurs when a regular expression exhibits catastrophic backtracking on certain inputs, causing CPU usage to spike and making the service unresponsive. In a FeathersJS application that uses Dynamodb as the persistence layer, this risk arises from how query parameters are built and passed to the database layer.
FeathersJS allows you to define hooks that transform incoming request queries into DynamoDB expressions. If these hooks use JavaScript RegExp objects to validate, sanitize, or transform parameters—especially on user-controlled strings such as search fields or filter values—the regex can be crafted to cause exponential backtracking. When the regex is applied in a hook before the query reaches DynamoDB, the Node.js event loop is blocked, and the 5–15 second scan window may reflect a hung or extremely slow operation during black-box testing.
Because DynamoDB does not execute JavaScript on the server, the regex runs inside your FeathersJS service logic. A typical vulnerable pattern is using a broad regex like /^(a+)+$/ to validate an ID or filter parameter. If an attacker sends a specially crafted string such as aaaaaaaaaaaaaaaaaaaa!, the regex engine may enter exponential backtracking, consuming high CPU. Even though the query never reaches DynamoDB, the service becomes unresponsive, effectively creating a denial-of-service vector in an otherwise NoSQL, server-side database stack.
The interaction with DynamoDB specifically matters because developers may assume that DynamoDB’s schema and query constraints provide safety against injection or abuse. However, validation and sanitization still happen in application code. If that code uses unsafe regex patterns on user input intended for DynamoDB expressions, the service layer is the weak point. This is particularly relevant when using features like filtering with the where parameter or dynamic key construction, where strings are concatenated into expression attribute names or values.
To detect this during a scan, middleBrick runs the endpoint unauthenticated and analyzes response behavior and timing. While it does not inspect internal implementation, a consistently slow response on certain payloads can indicate a regex DoS risk in the hooks or service logic that builds DynamoDB requests. The scanner’s LLM/AI security checks also probe for patterns that may lead to resource exhaustion through crafted inputs, highlighting endpoints where user data is processed with complex regular expressions before being passed to DynamoDB.
Dynamodb-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on removing or simplifying regular expressions and ensuring that user input is handled safely before it influences DynamoDB expressions. Prefer exact matching, allowlists, and bounded operations instead of open-ended repetition in patterns.
Avoid catastrophic backtracking in validation regex
Replace vulnerable regex patterns with safer alternatives. For example, if you are validating an identifier, use a simple pattern or direct character checks rather than nested quantifiers.
// Vulnerable: can cause catastrophic backtracking
const unsafePattern = /^(a+)+$/;
// Safer alternative: use bounded quantifiers or simple checks
const safePattern = /^a{1,32}$/;
// Or, for alphanumeric IDs, use a character class with a length limit
const idPattern = /^[A-Za-z0-9_-]{1,64}$/;
Apply this in a FeathersJS hook before building the DynamoDB expression:
// src/hooks/validate-query.js
const idPattern = /^[A-Za-z0-9_-]{1,64}$/;
module.exports = function validateQuery() {
return function(context) {
const { id } = context.params.query || {};
if (id && !idPattern.test(id)) {
throw new Error('Invalid query parameter: id');
}
// Proceed to build DynamoDB expression safely
return context;
};
};
Build DynamoDB expressions safely without regex transformations
When constructing ExpressionAttributeNames or ExpressionAttributeValues, avoid using user input directly in key paths. Use allowlists or mapping instead of regex-based replacement.
// src/services/items/service.js
const { DynamoDBDocumentClient, ScanCommand } = require("@aws-sdk/lib-dynamodb");
const ddbDocClient = DynamoDBDocumentClient.from(require("@aws-sdk/client-dynamodb"));
module.exports = {
async find(params) {
const { $select, ...query } = params.query;
const scanParams = {
TableName: process.env.DYNAMODB_TABLE || 'Items'
};
// Safe: map known fields to attribute names instead of regex substitution
const attributeNamesMap = {
name: 'name',
status: 'status',
createdAt: 'createdAt'
};
const expressionAttributeNames = {};
const expressionAttributeValues = {};
Object.keys(query).forEach(key => {
if (attributeNamesMap[key] !== undefined) {
expressionAttributeNames[`#${key}`] = attributeNamesMap[key];
expressionAttributeValues[`:${key}`] = query[key];
}
});
if (Object.keys(expressionAttributeNames).length > 0) {
scanParams.ExpressionAttributeNames = expressionAttributeNames;
}
if (Object.keys(expressionAttributeValues).length > 0) {
scanParams.ExpressionAttributeValues = expressionAttributeValues;
}
const command = new ScanCommand(scanParams);
const response = await ddbDocClient.send(command);
return response.Items;
}
};
Use framework-native validation and constraints
Leverage FeathersJS query validation hooks to enforce types and lengths, reducing the need for complex regex. Combine this with DynamoDB’s native type system to ensure only valid data is passed into expressions.
// src/hooks/validate-with-hooks.js
const { iff, isProvider, preventChanges } = require('feathers-hooks-common');
const { validateQuery } = require('./validate-query');
module.exports = {
before: {
all: [ preventChanges(['$id']) ],
find: [ validateQuery() ]
},
after: {
all: []
},
error: {
all: []
}
};
By avoiding regex-heavy validation and explicitly mapping user input to known DynamoDB attribute names, you reduce the attack surface and eliminate the risk of regex DoS while maintaining compatibility with unauthenticated scans that middleBrick performs.
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 |