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 Denial of Service via Exponential Time Complexity happens in brace-expansion and how to fix it

A high-severity Denial of Service vulnerability (CVE-2026-13149) was discovered in the brace-expansion npm package, where specially crafted input patterns could trigger exponential time complexity, potentially freezing Node.js applications. The fix upgrades multiple versions of brace-expansion (1.1.18 → 1.1.16, 2.1.1 → 2.1.2, and 5.0.6 → 5.0.7) through yarn resolutions to ensure all dependency paths use patched versions.

high

How Remote Code Execution via serialize-javascript happens in Node.js and how to fix it

The `serialize-javascript` package version 6.0.2 contained a high-severity Remote Code Execution (RCE) vulnerability (GHSA-5c6j-r48x-rmvq) exploitable through crafted `RegExp.flags` and `Date.prototype.toISOString()` payloads. Upgrading to version 7.0.3 eliminates the vulnerable serialization logic and removes the `randombytes` dependency that was part of the attack surface. This fix was applied via a `package.json` override and `package-lock.json` update.

critical

How unvalidated URL input handling happens in SvelteKit with Tauri and how to fix it

A critical vulnerability in `src/routes/+page.svelte` allowed attackers to supply arbitrary URLs—including `http://` and local file paths—through query parameters and drag-drop events, which were then fetched without validation. The fix restricts input to HTTPS-only URLs and removes the dangerous local file fetch path entirely, eliminating both SSRF and local file disclosure attack vectors.

critical

How SQL injection happens in Node.js string interpolation and how to fix it

A critical SQL injection vulnerability was discovered in the `getScript()` method of `src/core/statistics.js`, where the `metadata_id` variable was directly interpolated into DELETE and UPDATE SQL statements without any validation. An attacker controlling this parameter could inject malicious SQL payloads to delete entire tables or exfiltrate sensitive data. The fix implements strict input validation using `parseInt()` and regex patterns to ensure only safe values reach the database queries.

critical

How Command Injection happens in Python Flask and how to fix it

A critical command injection vulnerability was discovered in a Flask application's `/abc2xml` endpoint where user-supplied ABC music notation data could be weaponized to execute arbitrary shell commands. The `run_command` function used `subprocess.run()` with `shell=True` and string concatenation, allowing attackers to inject shell metacharacters. The fix switches to a list-based command invocation with `shell=False`, eliminating the injection vector entirely.

critical

How Security Bypass in Salesforce SOQL Queries Happens in Apex and How to Fix It

A critical security vulnerability in the ProductController.cls file allowed unauthorized users to bypass Salesforce's field-level and object-level security by executing unprotected SOQL queries. The fix adds a single `WITH USER_MODE` clause to enforce security checks, preventing guest users and unauthorized callers from accessing sensitive product data.