Regex Dos in Adonisjs with Cockroachdb
Regex Dos in Adonisjs with Cockroachdb — how this specific combination creates or exposes the vulnerability
AdonisJS, a Node.js web framework, often uses regular expressions to validate route parameters, query strings, or request payloads. When those regex patterns are complex, overly permissive, or constructed from user-influenced inputs, they can be susceptible to Regular Expression Denial of Service (ReDoS). In a setup using CockroachDB as the distributed SQL database, the interaction between AdonisJS request handling and CockroachDB queries can amplify the impact of such patterns, not because CockroachDB introduces regex risks, but because long-running validation can tie up Node.js event-loop resources and keep database connections or prepared statement pools occupied longer than necessary.
Consider an endpoint in AdonisJS that accepts a username parameter and uses a non-anchored, repetitive pattern to validate it, for example:
const usernameRegex = /^[a-z0-9]+(?!.*[!@#$%^&*])+$/i;
If crafted without care, patterns with overlapping quantifiers or ambiguous backtracking paths can cause catastrophic backtracking on carefully crafted long or malicious inputs. In an AdonisJS controller, you might see:
async store({ request }) {
const { username } = request.only(['username']);
const usernameRegex = /^[a-z0-9]+(?!.*[!@#$%^&*])+$/i;
if (!usernameRegex.test(username)) {
throw new Error('Invalid username');
}
const user = await User.query().where('username', username).first();
return user;
}
With CockroachDB, the query User.query().where('username', username).first() results in a distributed SQL round-trip. If the regex test is slow due to ReDoS characteristics, the Node.js event loop is blocked during validation, which can increase request latency and lead to resource saturation under concurrent malicious inputs. CockroachDB does not perform regex validation; however, the prolonged occupancy of database client sessions or prepared statement handles in the pool can exacerbate contention, especially under high concurrency. The vulnerability here is not in CockroachDB itself but in how AdonisJS handles input validation before issuing SQL, which becomes a bottleneck when the database backend is optimized for high-throughput distributed workloads.
Another scenario involves dynamic regex construction from route parameters or query strings, which is a classic anti-pattern. For instance:
async search({ request }) {
const { pattern } = request.get();
const dynamicRegex = new RegExp(pattern + '.*');
// ... use dynamicRegex
}
An attacker can supply a pattern designed to cause exponential backtracking. Even though the subsequent CockroachDB query might be efficient, the pre-processing phase becomes a single point of failure. This is particularly concerning in API security scans run by tools like middleBrick, which test inputs such as long strings or nested quantifiers to uncover such weaknesses. middleBrick’s checks for Input Validation and Unsafe Consumption are designed to surface these regex pathologies before they are exposed in production.
Additionally, when using OpenAPI/Swagger specs with regex patterns in parameter definitions (e.g., pattern: '^[a-z0-9]+$'), incomplete or incorrect $ref resolution can lead to inconsistent validation logic between documentation and implementation. middleBrick’s spec analysis cross-references definitions with runtime behavior, helping detect mismatches that could otherwise lead to ReDoS-prone validation paths when combined with CockroachDB-driven data access.
Cockroachdb-Specific Remediation in Adonisjs — concrete code fixes
Remediation focuses on avoiding regex-based validation that can exhibit exponential time complexity and ensuring that database interactions remain efficient and non-blocking. Below are concrete steps and code examples tailored for an AdonisJS application using CockroachDB.
1. Replace vulnerable regex patterns with safe, non-backtracking alternatives
Use simple character class checks or deterministic finite automata-friendly patterns. For alphanumeric usernames, prefer:
const isValid = /^[a-z0-9]+$/i.test(username) && !/[!@#$%^&*]/.test(username);
This avoids overlapping negative lookahead quantifiers that can cause backtracking. In AdonisJS, you can centralize validation logic:
// app/Validators/UserValidator.js
import { schema } from '@ioc:Adonis/Core/Validator';
export default class UserValidator {
public schema = schema.create({
username: schema.string({}, [
(value) => /^[a-z0-9]+$/i.test(value) || 'username must be alphanumeric',
(value) => !/[!@#$%^&*]/.test(value) || 'username contains invalid characters',
]),
});
}
2. Avoid dynamic regex construction
Do not construct RegExp from concatenated user input. If pattern building is necessary, use a strict allowlist of known-safe patterns:
const ALLOWED_PATTERNS = {
alphanumeric: '^[a-z0-9]+$',
slug: '^[a-z0-9_-]+$',
};
function getPattern(name) {
return ALLOWED_PATTERNS[name];
}
async search({ request }) {
const { type } = request.get();
const pattern = getPattern(type);
if (!pattern) {
throw new Error('Unsupported pattern type');
}
const regex = new RegExp(pattern);
// safe usage
}
3. Use framework validation hooks and leverage middleBrick for continuous checks
Integrate middleBrick’s CLI to scan your API endpoints regularly:
middlebrick scan https://api.yourservice.com/openapi.json
This helps detect input validation issues, including regex-related risks, without relying on internal architecture details. The CLI outputs structured findings that you can incorporate into your development workflow.
4. Optimize database interaction patterns with CockroachDB
Ensure queries are parameterized and use prepared statements to avoid SQL injection and improve performance. In AdonisJS with an ORM like Lucid, this is typically handled automatically, but be mindful of raw queries:
const user = await Database.from('users')
.select('id', 'username')
.where('username', username)
.limit(1);
Keep transactions short and avoid long-running operations in request handlers. CockroachDB performs well with indexed lookups; ensure your username column is indexed if used frequently in WHERE clauses.
5. Add runtime monitoring and rate limiting
Use AdonisJS middleware to enforce rate limits, reducing the chance of abuse targeting regex validation:
import { middleware } from '@ioc:Adioc/Http';
const limiter = middleware.create('throttle', {
max: 100,
windowMs: 60_000,
});
// Apply to routes in start/routes.ts
Route.post('/users', 'UserController.store').middleware([limiter]);
middleBrick’s Rate Limiting check can validate that such protections are in place and correctly configured.
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 |