Preventing ReDoS (Regular Expression Denial of Service) attacks in Express
How vulnerable regex patterns can freeze Node.js apps — and the practical steps to stop ReDoS attacks in Express 4 and 5.
.png)
One of my favorite sayings is that if you have a problem, and you solve it with regex, now you have two problems. Regular expressions are frequently used in Express apps for validating routes, user input, or query parameters. But if you’re not careful, a seemingly harmless regex can open your server to the dreaded Regular Expression Denial of Service (ReDoS) attack. This is one of the most common security flaws in modern software.
What a ReDoS Attack Is
A ReDoS happens when a vulnerable regex pattern causes the JavaScript regex engine (V8’s RegExp) to spiral into catastrophic backtracking.
In practice, an attacker sends input crafted to make your regex engine work overtime. Each new character can exponentially increase processing time — locking up your Node.js event loop and blocking every other request.
If you are interested in digging deeper into ReDoS attacks, check out our other blog: What are ReDoS Attacks
In Express 4, this means your entire app can hang even if a single route handler is validating one malicious input.
Example of a dangerous regex:
/^([a-zA-Z]+)+$/
Feed it something like "aaaaaaaaaaaaaaaaaaaaaaaaX" and watch CPU usage spike. The regex engine will try countless match combinations before finally failing.
How ReDoS Impacts Express Apps
Since Node.js is single-threaded, one long-running regex evaluation can freeze all other requests until it completes.
Common trouble spots include:
- Middleware that validates user input with regex
- Route params using regex (e.g. app.get('/:slug([a-zA-Z]+)+', handler))
- Libraries or dependencies that rely on unbounded regexes for parsing
Express (both v4 and v5) won’t protect you automatically — the framework doesn’t sandbox regex evaluation or enforce execution limits. There are some improvements in the new v5, but you can still be vulnerable if you aren’t careful.
Preventing ReDoS in Express 4
1. Audit and Harden Your Regexes
Use tools like:
- safe-regex — flags catastrophic patterns
- rxxr2 — deeper static analysis for ReDoS risks
- @wesleytodd/openapi — suite of documentation and generation tools
Use these for any regex used in your routes, middleware, or data validation logic.
2. Avoid Complex or Nested Quantifiers
Patterns like (.*)+, (a|aa)+, or ([a-z]+)* are classic ReDoS triggers.
Simplify them or switch to explicit, bounded quantifiers:
/^[a-z]{1,50}$/ // much safer
3. Limit Input Length
Before applying regexes, limit request body, query, or param sizes:
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ limit: '10kb', extended: false }));
This keeps attackers from feeding enormous payloads into your regex engine.
4. Use Trusted Validation Libraries
Instead of writing custom regexes, use libraries designed with performance and safety in mind:
These libraries avoid vulnerable regex patterns and add type-safe validation.
5. Upgrade to Express 5
Express 5 protects you in two ways:
First, it uses the latest version of path-to-regex which has a lot of safety improvements.
Second, it no longer allows sub-expression regular expressions - such as /:foo(\\d+) which eliminates one of the main possibilities for ReDoS attacks.
If you are stuck on Express 3, you can use HeroDevs for security updates with Express 3. This addresses all of the known attack vectors common in these older versions of Express.
TL;DR
- ReDoS = Regex + Catastrophic Backtracking + Single Thread = Frozen Server
- Express doesn’t protect you out-of-the-box
- Audit your regexes, limit input sizes, and rely on trusted validation libraries
With a few safety checks and better patterns, your Express app will stay fast, responsive, and immune to the sneakiest form of DoS in JavaScript land.
.png)
.png)
