Regex Dos in Express with Cockroachdb
Regex Dos in Express with Cockroachdb — how this specific combination creates or exposes the vulnerability
A Regular Expression Denial of Service (Regex DoS) in an Express application using CockroachDB can occur when untrusted input is used to construct dynamic SQL queries or passed into regex operations without constraints. In this stack, an attacker can supply a carefully crafted string that causes catastrophic backtracking in a JavaScript regex or in a pattern that is translated into SQL by an ORM or query builder. Because CockroachDB is compatible with PostgreSQL wire protocol, many Node.js drivers and ORMs use parameterized queries; however, if regex patterns or LIKE/ILIKE fragments are built by string concatenation, the unsafe input directly influences how the database processes the pattern.
Express routes often accept identifiers or search terms that are used both in application-level validation (e.g., regex tests on req.params or req.query) and in database queries. When these values are interpolated into SQL strings or ORM conditions without proper sanitization, two classes of risk appear: (1) JavaScript regex engine can hang due to exponential backtracking on maliciously crafted input; (2) patterns passed to CockroachDB via LIKE/ILIKE or through ORM escaping may still force full scans or complex pattern matching if the input is not bounded, especially when wildcard characters such as % and _ are user-controlled.
An example scenario: an endpoint GET /search/:term builds a LIKE clause by concatenating '%' + term + '%'. If term contains repeated characters and wildcards, and the regex or pattern logic is also applied in JavaScript before query construction, the combined effect can amplify CPU usage on both the Node.js process and the CockroachDB nodes. Moreover, if the application uses dynamic regex generation to enforce format rules on identifiers before submitting SQL to CockroachDB, an attacker can supply a pattern that causes the regex engine to consume excessive stack and event-loop time, leading to resource exhaustion that manifests as high latency or timeouts across the service.
Because middleBrick scans the unauthenticated attack surface and tests input validation and SQL/NoSQL behavior in parallel checks, it can surface these classes of vulnerability by observing anomalous response behavior and by correlating findings from the Input Validation and Property Authorization checks with SQL pattern handling. The scanner does not fix the issue but provides findings with severity, prioritization, and remediation guidance to help teams tighten input constraints and avoid unbounded pattern operations.
Cockroachdb-Specific Remediation in Express — concrete code fixes
Defensive programming and strict input validation are essential when Express routes interact with CockroachDB. Use parameterized queries or prepared statements for all SQL operations, and avoid building SQL fragments via string concatenation. For pattern matching, push as much filtering as possible into the database using bounded parameters, and if regex is required in JavaScript, ensure patterns are static or strictly bounded and applied only on already-sanitized input.
Example: Safe parameterized query with an indexed lookup
const express = require('express');
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
const app = express();
app.get('/user/:email', async (req, res) => {
const email = req.params.email;
// Basic format validation with a strict, non-backtracking pattern
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!emailRegex.test(email)) {
return res.status(400).json({ error: 'Invalid email format' });
}
try {
const result = await pool.query('SELECT id, name FROM users WHERE email = $1', [email]);
if (result.rows.length === 0) {
return res.status(404).json({ error: 'Not found' });
}
res.json(result.rows[0]);
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Internal server error' });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
Example: Bounded LIKE with parameterization and no wildcard injection
app.get('/search', async (req, res) => {
const term = req.query.q;
if (typeof term !== 'string' || term.length > 100) {
return res.status(400).json({ error: 'Invalid query' });
}
// Use explicit bound pattern; avoid concatenating user input into the pattern
const safePattern = '%' + term.replace(/%/g, '\%').replace(/_/g, '\_') + '%';
try {
const result = await pool.query('SELECT id, title FROM items WHERE title ILIKE $1 ESCAPE \'\\\'', [safePattern]);
res.json(result.rows);
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Search failed' });
}
});
Recommendations
- Always use parameterized queries with $1, $2 placeholders in pg-based drivers to CockroachDB.
- Validate and sanitize inputs before using them in regex or SQL LIKE patterns; reject inputs that contain uncontrolled wildcards or excessive length.
- Keep regex patterns static and avoid building patterns from user input; if dynamic patterns are unavoidable, use strict length and character class limits and prefer non-backtracking constructs or atomic groups where supported by the regex engine.
- Monitor query plans and indexes in CockroachDB to ensure pattern-based lookups do not degrade into full scans; enforce length and format constraints at the API layer.
By combining strict input validation, parameterized SQL, and bounded pattern usage, you reduce the risk of Regex DoS across both the Node.js runtime and CockroachDB, while keeping the API responsive and predictable.
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 |