Back to Blog
critical SEVERITY6 min read

How ReDoS Vulnerabilities Happen in Node.js Express Applications and How to Fix Them

A critical Regular Expression Denial of Service (ReDoS) vulnerability in the path-to-regexp package (CVE-2024-45296) was discovered in the lacartoons-addon project's dependency tree. The vulnerable versions used backtracking regular expressions that could cause catastrophic performance degradation when processing malicious route patterns. Upgrading to patched versions (0.1.10 for Express's internal router) eliminates this attack vector.

O
By Orbis AppSec
Published August 5, 2026Reviewed August 5, 2026

Answer Summary

CVE-2024-45296 is a ReDoS (Regular Expression Denial of Service) vulnerability in path-to-regexp, a Node.js package used by Express for route matching. The vulnerability (CWE-1333) occurs when backtracking regular expressions process crafted input, causing exponential time complexity. The fix involves upgrading path-to-regexp to version 0.1.10 or higher, which eliminates the problematic regex patterns that enable catastrophic backtracking.

Vulnerability at a Glance

cweCWE-1333
fixUpgrade path-to-regexp from 0.1.7 to 0.1.10
riskService unavailability through CPU exhaustion
languageJavaScript/Node.js
root causeBacktracking regex patterns in path-to-regexp route matching
vulnerabilityRegular Expression Denial of Service (ReDoS)

Introduction

The lacartoons-addon project, a Stremio addon built with Express.js, contained a critical vulnerability hiding in its dependency tree. The path-to-regexp package at version 0.1.7—used internally by Express's router module—was susceptible to CVE-2024-45296, a ReDoS vulnerability that could allow attackers to crash the service with carefully crafted URL patterns.

Looking at the package-lock.json, we can see the vulnerable dependency chain:

"node_modules/router/node_modules/path-to-regexp": {
  "version": "0.1.7",
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
}

This matters because any Express application exposing routes to user input—which is virtually all of them—becomes a potential target. For a streaming addon handling requests from Stremio clients, a single malicious request could render the entire service unresponsive.

The Vulnerability Explained

What is ReDoS?

Regular Expression Denial of Service (ReDoS) exploits a fundamental weakness in how regex engines process certain patterns. When a regex contains nested quantifiers or overlapping alternatives, the engine may need to try an exponentially growing number of paths to determine if a string matches.

The Vulnerable Pattern in path-to-regexp

The path-to-regexp library converts Express route strings like /user/:id into regular expressions for matching incoming requests. In version 0.1.7, the generated regex patterns contained constructs vulnerable to catastrophic backtracking.

Consider how Express routes work:

// In a typical Express application using stremio-addon-sdk
app.get('/catalog/:type/:id/:extra?.json', (req, res) => {
  // Handle catalog requests
});

The path-to-regexp library transforms this route pattern into a regex. In vulnerable versions, patterns with optional parameters (:extra?) and complex path structures generated regex with nested quantifiers.

How the Attack Works

An attacker could craft a URL designed to trigger exponential backtracking:

GET /catalog/movie/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!

When the regex engine attempts to match this against a route pattern, it may enter a state where it tries millions or billions of combinations before determining the string doesn't match. Each additional character can double the processing time.

For the lacartoons-addon specifically, routes like:

// Stremio addon routes typically include
/stream/:type/:id.json
/catalog/:type/:id.json
/meta/:type/:id.json

Any of these endpoints could be targeted with malicious input, causing the Node.js event loop to block while the regex engine churns through backtracking paths.

Real-World Impact

For this Stremio addon:
- Service Unavailability: A single malicious request could freeze the addon for seconds or minutes
- Cascading Failures: Multiple concurrent attacks could exhaust all available CPU
- No Authentication Required: The attack works against public endpoints
- Amplification: Attackers can automate requests, multiplying the impact

The Fix

The fix involves upgrading path-to-regexp to patched versions that eliminate the vulnerable regex patterns. Let's examine the specific changes in package-lock.json:

Before (Vulnerable)

"node_modules/router/node_modules/path-to-regexp": {
  "version": "0.1.7",
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
}

After (Fixed)

"node_modules/express/node_modules/path-to-regexp": {
  "version": "0.1.10",
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
  "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
  "license": "MIT"
}

Key Changes Explained

  1. Version Upgrade: The vulnerable 0.1.7 is replaced with 0.1.10, which contains fixes for CVE-2024-45296

  2. Dependency Tree Restructuring: The fix also removed a standalone path-to-regexp at version 8.4.2:
    diff -"node_modules/path-to-regexp": { - "version": "8.4.2",
    This consolidates the dependency and ensures all route matching uses the patched version.

  3. Node.js Engine Requirement: The fix adds an engine constraint:
    json "engines": { "node": ">=18.0.0" }
    This ensures the application runs on Node.js versions with improved regex performance and security features.

  4. License Clarification: Changed from ISC to MIT license, aligning with the dependency's license.

How the Patched Version Fixes ReDoS

Version 0.1.10 of path-to-regexp rewrites the regex generation logic to:
- Avoid nested quantifiers that cause exponential backtracking
- Use atomic grouping patterns where possible
- Limit the complexity of generated expressions
- Add safeguards against pathological input patterns

Prevention & Best Practices

1. Keep Dependencies Updated

# Regularly audit dependencies
npm audit

# Update to patched versions
npm update

# Use automated tools like Dependabot or Renovate

2. Monitor for CVEs in Your Dependency Tree

The vulnerability existed in a transitive dependency (router → path-to-regexp), not a direct dependency. Use tools that scan the entire dependency tree:

# Trivy scanning (as used in this detection)
trivy fs --scanners vuln .

# npm's built-in audit
npm audit --all

3. Implement Request Timeouts

Even with patched dependencies, add defense in depth:

const express = require('express');
const app = express();

// Set request timeout
app.use((req, res, next) => {
  req.setTimeout(5000, () => {
    res.status(408).send('Request Timeout');
  });
  next();
});

4. Input Validation Before Route Matching

Validate URL length and character sets before Express processes routes:

app.use((req, res, next) => {
  if (req.url.length > 2048) {
    return res.status(414).send('URI Too Long');
  }
  next();
});

5. Use Rate Limiting

Limit requests to mitigate automated attacks:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per window
});

app.use(limiter);

Key Takeaways

  • Transitive dependencies matter: The vulnerability was in path-to-regexp 0.1.7, a dependency of Express's router, not a direct project dependency
  • Stremio addons using stremio-addon-sdk inherit Express vulnerabilities: Any addon built on this SDK should verify their path-to-regexp version
  • ReDoS attacks require no authentication: Public endpoints in the lacartoons-addon like /catalog/:type/:id.json were all potential attack vectors
  • Trivy correctly identified CVE-2024-45296 in package-lock.json: Automated scanning caught this before exploitation
  • The fix required careful dependency tree management: Simply updating one package wasn't enough; the entire dependency resolution needed adjustment

How Orbis AppSec Detected This

  • Source: HTTP request URLs processed by Express route matching in the lacartoons-addon
  • Sink: path-to-regexp regex execution within Express's router module (transitive dependency via stremio-addon-sdk)
  • Missing control: No protection against backtracking regex patterns in route matching; vulnerable path-to-regexp version 0.1.7 in dependency tree
  • CWE: CWE-1333 (Inefficient Regular Expression Complexity)
  • Fix: Upgraded path-to-regexp from 0.1.7 to 0.1.10 in the Express router dependency, eliminating vulnerable regex patterns that enabled catastrophic backtracking

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2024-45296 in path-to-regexp demonstrates how a vulnerability in a deeply nested dependency can expose your entire application to denial of service attacks. The lacartoons-addon, like many Express-based applications, was vulnerable simply by using standard routing patterns.

The fix was straightforward—a dependency upgrade—but finding it required scanning the complete dependency tree. This underscores the importance of automated security scanning that goes beyond direct dependencies to examine the full package-lock.json.

For Node.js developers: regularly audit your dependencies, implement defense-in-depth measures like request timeouts and rate limiting, and consider the security implications of every package in your dependency tree, no matter how deeply nested.

References

Frequently Asked Questions

What is ReDoS?

ReDoS (Regular Expression Denial of Service) is an attack where specially crafted input causes a regular expression to take exponentially long to evaluate, consuming CPU resources and potentially crashing the application.

How do you prevent ReDoS in Node.js?

Prevent ReDoS by using non-backtracking regex patterns, setting timeout limits on regex execution, validating input length before regex processing, and keeping dependencies like path-to-regexp updated.

What CWE is ReDoS?

ReDoS is classified under CWE-1333 (Inefficient Regular Expression Complexity) and is related to CWE-400 (Uncontrolled Resource Consumption).

Is input validation enough to prevent ReDoS?

Input validation helps but isn't sufficient alone. You must also ensure the regex patterns themselves don't contain vulnerable constructs like nested quantifiers that enable catastrophic backtracking.

Can static analysis detect ReDoS?

Yes, tools like Trivy, Semgrep, and specialized regex analyzers can detect potentially vulnerable regex patterns and known vulnerable dependencies like path-to-regexp versions affected by CVE-2024-45296.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #23

Related Articles

high

How Octal IP Address Parsing Inconsistency Enables SSRF in Node.js and How to Fix It

A critical parsing inconsistency in the `ip-address` npm package (version 10.2.0) allowed attackers to bypass SSRF protections by exploiting how leading-zero octets are interpreted differently—decimal by the library versus octal by system resolvers. This vulnerability (CVE-2026-69192) was fixed by upgrading to version 10.3.1 using an npm override, ensuring consistent IP address validation across the application.

high

How Command Injection Happens in Node.js Child Process Calls and How to Fix It

A Node.js library was vulnerable to command injection through unsafe use of `execSync()` with shell string interpolation in the `index.js` file. By switching to `execFileSync()` with argument arrays, the fix eliminates the ability for attackers to inject shell metacharacters through file paths. This change demonstrates a critical security hardening pattern for any Node.js code that spawns child processes.

high

How NO_PROXY bypass via crafted URL happens in Node.js axios and how to fix it

A high-severity vulnerability (CVE-2026-42043) in the axios HTTP client library allowed attackers to bypass NO_PROXY environment variable restrictions using specially crafted URLs. This could route sensitive internal traffic through attacker-controlled proxy servers. The fix upgrades axios from 1.13.6 to 1.18.0, which includes a rewritten proxy resolution mechanism using `proxy-from-env` v2.1.0 and the `https-proxy-agent` package.

high

How Denial of Service via Infinite Loop happens in Node.js dependencies and how to fix it

A high-severity vulnerability in the nanoid package (CVE-2026-67213) allowed attackers to trigger infinite loops through the customAlphabet function, potentially causing complete denial of service. This fix upgrades nanoid from version 3.3.16 to 3.3.17 in the app_store dependency tree, eliminating the DoS risk through a simple version override.

high

How Denial of Service via Deeply Nested Field Names Happens in Node.js Multer and How to Fix It

A high-severity Denial of Service vulnerability (CVE-2026-5079) was discovered in the multer package, a popular Node.js middleware for handling multipart form data. Attackers could craft malicious requests with deeply nested field names to exhaust server resources. The fix upgrades multer from version 2.0.2 to 2.2.0, which implements proper limits on field name parsing depth.

critical

How SQL Injection happens in PHP PDO queries and how to fix it

A critical SQL injection vulnerability was discovered in the `getOfficialContests()` method of ContestRepository.php, where the `$site_id` parameter was directly interpolated into a SQL query string instead of using prepared statements. This vulnerability allowed attackers to inject arbitrary SQL commands and potentially access or manipulate the entire contest database. The fix replaced `pdo->query()` with `pdo->prepare()` and proper parameter binding.