Regex Dos in Feathersjs with Cockroachdb
Regex Dos in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
Regex Denial-of-Service (ReDoS) occurs when a regular expression has patterns that can cause catastrophic backtracking on certain inputs. In a Feathersjs application using Cockroachdb as the data store, this risk appears at two points: (1) in user-controlled inputs that Feathers services may validate using JavaScript RegExp, and (2) in potential misuse of service query parameters that are transformed into SQL WHERE clauses by Feathers adapters. Although Cockroachdb itself does not introduce regex, the way Feathers builds queries and validates payloads can magnify the impact when regex is used on untrusted data before reaching the database.
Feathersjs encourages a service-oriented model where validation often happens in hooks. A common pattern is to use regex to validate strings such as emails, slugs, or IDs. If an attacker provides an exponentially ambiguous pattern (e.g., /(a+)+$/) and a long malicious string, the regex engine can consume excessive CPU, causing thread starvation and request timeouts. Because Feathers services are typically long-running Node.js processes, this can degrade performance for all connections, even when Cockroachdb remains responsive.
Another vector involves dynamic query building. If a Feathers hook constructs a Cockroachdb SQL string by concatenating user input that is first processed through a regex, an attacker can supply crafted input that forces the regex engine to backtrack heavily before the query is sent. Cockroachdb is resilient to many SQL-level attacks, but the intermediary regex processing sits in the Node.js runtime and can block the event loop independently of the database. This means even though Cockroachdb enforces strong consistency and handles distributed workloads well, the application layer can become the bottleneck if regex is applied carelessly.
Real-world examples include validating identifiers with overly permissive character classes or using greedy quantifiers on unbounded input. For instance, a hook that validates a tag parameter with /^[a-zA-Z0-9_]+$/ is generally safe, but changing it to /^[a-zA-Z0-9_]*$/ or using nested groups can introduce subtle risks when combined with malformed UTF-8 or extremely long strings. Feathers hooks that rely on external validation libraries or custom regex should explicitly limit input length and avoid patterns with overlapping quantifiers, especially when the validated values later influence SQL generation for Cockroachdb.
Because Feathers does not enforce a schema on query parameters by default, developers must manually sanitize and validate inputs. If regex validation is used as the primary defense, ensure patterns are atomic, avoid optional repeated groups, and prefer explicit length checks. Tools that analyze regex complexity can help identify problematic constructs before they reach production. In short, the combination of Feathersjs flexibility and Cockroachdb robustness does not inherently create ReDoS, but poor regex hygiene in hooks and query building can undermine the stability of the entire service layer.
Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes
To mitigate regex-related risks in a Feathersjs service backed by Cockroachdb, focus on deterministic validation, bounded input lengths, and avoiding regex for complex structural checks. Below are concrete patterns and code examples that reduce the chance of ReDoS while preserving compatibility with Cockroachdb.
- Use safe, bounded validation with explicit length limits:
// Good: bounded length and simple character class
const SAFE_REGEX = /^[
a-zA-Z0-9_-]{1,64}$/;
app.service('users').hooks({
before: {
create(context) {
const { slug } = context.data;
if (!SAFE_REGEX.test(slug)) {
throw new Error('Invalid slug format');
}
return context;
}
}
});
- Prefer non-regex validation for identifiers and enforce constraints at the database level using Cockroachdb CHECK constraints:
// Feathers hook that enforces rules without complex regex
app.service('posts').hooks({
before: {
create(context) {
const { title } = context.data;
if (typeof title !== 'string' || title.length === 0 || title.length > 200) {
throw new Error('Title must be a string between 1 and 200 characters');
}
return context;
}
}
});
On the Cockroachdb side, define a table with a CHECK constraint to reject invalid data at the storage layer:
CREATE TABLE posts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title STRING NOT NULL CHECK (length(title) >= 1 AND length(title) <= 200),
created_at TIMESTAMPTZ DEFAULT now()
);
- Replace complex regex with deterministic parsing for structured fields like emails:
// Avoid regex for email; use a lightweight parser and length guard
function isValidEmail(value) {
if (typeof value !== 'string' || value.length > 254) return false;
const parts = value.split('@');
return parts.length === 2 && parts[0].length > 0 && parts[1].length > 0 && parts[1].includes('.');
}
app.service('contacts').hooks({
before: {
create(context) {
if (!isValidEmail(context.data.email)) {
throw new Error('Invalid email');
}
return context;
}
}
});
- When regex is unavoidable, use atomic groups and avoid nested quantifiers; test patterns against malicious payloads using a harness:
// Use a safe pattern with atomic groups and bounded repeats
const SAFE_TAG_REGEX = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*){1,10}$/i;
// Test harness to detect catastrophic backtracking
function testRegex(pattern, inputs) {
const re = new RegExp(pattern);
const start = Date.now();
for (const input of inputs) {
re.test(input);
if (Date.now() - start > 50) {
throw new Error('Regex too slow');
}
}
}
By combining input length limits, schema-level constraints in Cockroachdb, and cautious regex usage, Feathersjs services remain performant and resilient against ReDoS while maintaining compatibility with distributed SQL workloads.
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 |