The path-to-regexp library can, under very common route patterns, generate regular expressions that trigger catastrophic backtracking — a bug tracked as CVE-2024-45296 that can freeze Node.js servers and create an easy, low‑complexity Denial‑of‑Service (DoS) vector against applications that rely on this package for routing.
path-to-regexp is a tiny but ubiquitous utility used to compile human-friendly route strings (like /user/:id) into JavaScript regular expressions that frameworks and routers use to match incoming request URLs. Because it sits squarely in the HTTP request path, its correctness and efficiency are security‑critical: the generated regex runs on the Node.js main thread, and any pathological regex can block the event loop until it finishes, taking the whole process with it.
In September 2024 the project and major security databases assigned CVE-2024-45296 to a pattern in path-to-regexp that produces backtracking-prone regular expressions whenever two parameters appear inside the same path segment and are separated by a character other than a dot (for example, /:a-:b). Upstream maintainers released fixes and new major versions that either add backtrack protection or remove the risky features entirely. However, the vulnerability deserves careful real‑world attention because routing patterns like the example above are common and easy to introduce through either application code or user-supplied route templates.
Example "bad" route:
Worst-case input shape:
const re = pathToRegexp('/:a-:b'); // may produce backtracking-prone regex
function timeMatch(input) {
const start = process.hrtime.bigint();
re.exec(input);
const end = process.hrtime.bigint();
return Number(end - start) / 1e6; // milliseconds
}
const attack = '/a' + '-a'.repeat(8000) + '/a';
console.log('match ms:', timeMatch(attack));
Actionable prioritized recommendations:
CVE-2024-45296 is a practical lesson in how simple API conveniences (multiple parameters inside one URL segment) can inadvertently generate dangerous artifacts (backtracking-prone regular expressions). The good news is that upstream patches and version upgrades are available; the bad news is that the vulnerability is trivial to trigger from the network and straightforward to exploit at scale. The right combination of fast inventory, immediate compensating controls, and prioritized upgrades will reduce your exposure quickly and decisively.
Source: MSRC Security Update Guide - Microsoft Security Response Center
Background
path-to-regexp is a tiny but ubiquitous utility used to compile human-friendly route strings (like /user/:id) into JavaScript regular expressions that frameworks and routers use to match incoming request URLs. Because it sits squarely in the HTTP request path, its correctness and efficiency are security‑critical: the generated regex runs on the Node.js main thread, and any pathological regex can block the event loop until it finishes, taking the whole process with it.In September 2024 the project and major security databases assigned CVE-2024-45296 to a pattern in path-to-regexp that produces backtracking-prone regular expressions whenever two parameters appear inside the same path segment and are separated by a character other than a dot (for example, /:a-:b). Upstream maintainers released fixes and new major versions that either add backtrack protection or remove the risky features entirely. However, the vulnerability deserves careful real‑world attention because routing patterns like the example above are common and easy to introduce through either application code or user-supplied route templates.
Overview of the vulnerability
What goes wrong (short answer)
When a route segment contains two parameter tokens separated by a non-dot character, path-to-regexp compiles it into a capturing-group pattern that allows many ways to divide the input between the two captures. That ambiguity translates into exponential backtracking for specific crafted inputs, which in turn causes heavy CPU use on the single Node.js thread and can make a server unresponsive.Example "bad" route:
- /:a-:b
- /^\/([^\/]+?)-([^\/]+?)\/?$/
Why JavaScript servers are particularly exposed
JavaScript servers (Node.js) handle events and I/O on a single main thread. Regex matching is performed synchronously on that thread. If the regex takes very long to evaluate, it prevents asynchronous callbacks, other request handling, timers, and even health-check responses from running — effectively turning a resource exhaustion problem into a total service outage in many environments.Attack model and impact
- Attack vector: network (an HTTP request URL).
- Privileges required: none.
- Complexity: low — the attacker only needs to send crafted requests.
- Impact: high availability loss (sustained while the attack is active, or repeated exploitation causing persistent unavailability). The flaw is a textbook Regular Expression Denial of Service (ReDoS).
- Scope: applications and libraries that include vulnerable versions of path-to-regexp (directly or transitively), including many routers and web frameworks.
A technical deep dive
How the regex becomes backtracking-prone
path-to-regexp’s goal is to convert tokenized routes into a single regular expression that will match and capture parameters. For a segment like:a-:b, path-to-regexp generates two adjacent capture groups separated by a literal -, each using a greedy or lazy quantifier that accepts anything except /. The regex engine must decide how many characters to assign to the first capture versus the second for every possible split; with long inputs, the number of candidate splits grows linearly with input length and the backtracking combinatorics make time complexity balloon, sometimes exponentially, depending on pattern structure.Worst-case input shape:
- Long repetition of a pattern that can be consumed by either capture, followed by a trailing element that makes the overall route fail (forcing full backtracking). Example conceptually:
/a${'-a'.repeat(8000)}/a— the trailing/aensures the entire route cannot match, so the regex explores all splits before failing.
Example (conceptual)
Vulnerable route:- '/:a-:b'
- /^\/([^\/]+?)-([^\/]+?)\/?$/
- '/a-a-a-a-...-a/a' (very long repetition between slashes)
- The engine tries many splits for the two captures; CPU skyrockets; Node’s event loop stalls.
Limits of fixes and edge cases
- Upstream fixes add backtrack protection around automatically generated capture groups when no explicit custom regex is supplied. This reduces the engine’s ability to try enormous numbers of splits.
- However, user-supplied capture patterns (explicit regexes written into route templates) are outside the automated protection strategy in many fixes: if an application author writes a custom capture that itself is backtracking‑prone, the library cannot reliably protect against that.
- Major rewrites (newer major versions) remove or restructure the APIs/features that enable the dangerous expansions entirely in order to eliminate the class of risky outputs.
Affected versions and vendor response
- A broad set of older path-to-regexp versions are affected. Patches were released on specific maintenance branches and a new major version removes risky features.
- The practical remediation advice from maintainers is:
- For the old 0.1.x train: upgrade to the patched 0.1.10 (or later patch within that train).
- For other series: upgrade to the new safe release (for many users that means upgrading to the 8.x stream which removes the risky behavior).
- Specific intermediate maintenance releases (for example, 1.9.0, 3.3.0, 6.3.0, and others from the maintenance matrix) add backtrack protection and are safe for the default-case patterns.
- The fixes intentionally leave explicit user regexes alone: if code uses custom capture groups, developers must review those expressions themselves.
Real-world exposure: where this matters
path-to-regexp is used either directly or indirectly in many routing stacks and libraries. A non-exhaustive list of common places where this can appear includes:- Web frameworks and routers (Express-style routers, koa-router, some versions of React Router internals, custom routers).
- API gateways or microservice frameworks that build routing tables dynamically from service configuration.
- Enterprise products and middleware that embed Node.js and use the package for URL pattern matching.
Detection and hunting
To find vulnerable usage and potential exploitation, follow a structured approach:- Inventory:
- Run automated SBOM / dependency scanners (npm audit, OSS supply-chain tools, container scanners) against application source and build artifacts to identify path-to-regexp versions.
- Inspect lockfiles (package-lock.json / yarn.lock / pnpm-lock.yaml) and verify resolved versions, including transitive dependencies.
- Static pattern checks:
- Search code and templates for route patterns containing multiple parameters in a single segment (tokens like
:foomore than once between two slashes, e.g.,/:a-:b,/:id_name:other, or other non-dot separators). - Flag any explicit custom regex captures (expressions inside parentheses after parameter identifiers) for manual review.
- Runtime detection:
- Add logging and instrumentation around route compilation and regex execution where possible.
- Monitor per-request CPU spikes and latency spikes correlating with request URL shapes.
- Watch for patterns in access logs: repeated unusually long URLs, repeated failures of a route that eventually time out, or a stream of slow requests that coincide with CPU saturation.
- Canary testing:
- In staging, feed candidate exploit strings (long repeated segments designed to trigger backtracking) against a testbed of your router stack to measure matching time and behavior. This should be done carefully and isolated, because it will consume CPU.
- Detection signatures (examples to watch for in logs):
- Long path strings containing a repeated motif and used many times in a short window.
- Abnormally long route match times compared to baseline for the same endpoint.
Immediate mitigations and workarounds
If you discover vulnerable versions in your environment and cannot upgrade immediately, apply layered mitigations:- Limit request URL length
- Add server-side caps on maximum URL length. While this does not eliminate the risk (it only reduces the worst-case work factor), it can drastically increase the cost of triggering catastrophic backtracking.
- Many implementations show a near-quadratic relation between attack length and CPU time; cutting allowed URL length reduces feasible attack complexity.
- Use explicit, safe parameter patterns
- Rewrite vulnerable path templates so that later parameters in a single segment have explicit, bounded patterns that do not overlap the text before them.
- Example: change
/:a-:bto/:a-:b([^-/]+)— the custom pattern excludes the separator and thus prevents ambiguous splits. - Apply rate limiting and request throttling
- Protect exposed endpoints with per-IP and per-route rate limits at the application or edge tier to reduce the ability for attackers to mount sustained request floods.
- Web Application Firewall (WAF)
- Deploy WAF rules to block dangerously long or repeated-pattern URLs, or to block requests matching heuristics of a backtracking exploit.
- Move risky pattern matching off the main thread
- For extremely high-risk systems, consider architecture changes where expensive regex or matching work runs in a worker thread or a separate process so one stalled match does not paralyse the whole server.
- Use the strict-mode guard (if available in your version)
- Some intermediate versions provide a
strictoption which throws or refuses to compile routes that appear unsafe. Enable these options where supported and feasible. - Block or validate user-supplied templates
- If your system accepts route templates from users or configuration, sanitize and validate templates to prevent the introduction of risky multi-parameter forms.
Long-term remediation: upgrade and harden
- Prioritize upgrading to a patched release
- The authoritative fix path is to upgrade path-to-regexp to a patched release train. For many projects this means moving to the 8.x stream which removes the features that allow generating the dangerous patterns, or to one of the maintenance releases that add backtrack protection.
- Because the library is often transitive, verify transitive upgrades in your dependency graph and rebuild artifacts after the upgrade.
- Test compatibility
- Upgrading a routing library can change subtle semantics. Run the test suite and exercise routing behavior thoroughly — especially routes that use custom regexes or advanced parameter features.
- Audit custom regexes
- Manually review any custom capture groups in route templates. Even in patched library versions, user-supplied regexes may be unsafe.
- Add defensive coding standards
- Enforce code reviews and static checks that flag patterns with multiple parameters in a single segment.
- Add linter rules or custom tests that detect and fail CI builds on vulnerable route patterns.
- Improve observability
- Add request-duration histograms keyed by route path pattern.
- Alert on sudden spikes in regex/matching latency or event-loop lag.
- Harden public-facing entry points
- Move rate limiting and other protections to the edge (CDN, API gateway) so that malformed or abusive requests can be stopped before hitting origin servers.
Practical remediation checklist (operational, step-by-step)
- Inventory
- 1.) Run dependency scanning across source repositories and built artifacts to list occurrences of path-to-regexp and its resolved versions.
- 2.) Identify which products and services include vulnerable versions (direct or transitive).
- Risk triage
- 1.) Classify exposure: public internet-facing service = high priority; internal service = medium; CI/test environment = low.
- 2.) Identify routes that include multiple parameters in a single segment or that accept user-supplied route templates.
- Short-term mitigations
- 1.) Apply URL-length limits at web servers or application middleware.
- 2.) Add / enable rate limits for suspicious endpoints.
- 3.) Create WAF rules to block obviously malicious path patterns.
- Medium-term remediation
- 1.) Upgrade path-to-regexp to the patched maintenance release or to the major version that removes the risky behavior.
- 2.) Rebuild, test, and deploy all affected services and containers.
- 3.) Rotate any configuration or policies that allowed user-defined route templates until templates are validated.
- Long-term hardening
- 1.) Introduce linter and CI checks for route patterns.
- 2.) Add coverage tests that assert acceptable match latency for representative long inputs.
- 3.) Enhance logging and alerting around route compile failures and long-running matches.
Example code and tests
NOTE: The following examples are conceptual and intended for controlled testing only. Do not run exploit strings against production systems.- Detect vulnerable compiled regex timing:
Code:const pathToRegexp = require('path-to-regexp');
const re = pathToRegexp('/:a-:b'); // may produce backtracking-prone regex
function timeMatch(input) {
const start = process.hrtime.bigint();
re.exec(input);
const end = process.hrtime.bigint();
return Number(end - start) / 1e6; // milliseconds
}
const attack = '/a' + '-a'.repeat(8000) + '/a';
console.log('match ms:', timeMatch(attack));
Code:
- Safer alternative: explicit capture for the second parameter
```js
const safeRe = pathToRegexp('/:a-:b([^-/]+)');
- CI test: assert match time under a threshold in staging
Code:const ms = timeMatch(attack); if (ms > 500) { throw new Error(`Route match too slow: ${ms}ms`); }
What operators often miss (risks and caveats)
- Transitive dependence blind spots: many teams only scan direct dependencies. When a transitive package contains the vulnerable library, it's easy to miss unless lockfiles and SBOMs are inspected.
- Runtime feature flags and options: some router wrappers expose options that change compilation semantics; enabling strictness in one library might not protect another wrapper that compiles its own regexes.
- User-supplied expressions: automated fixes that wrap or rewrite unsafe generated regexes do not (and cannot) make arbitrary user-specified regexes safe. Applications that let administrators or end users provide custom regex templates must validate those expressions.
- False sense of security after short-term mitigations: URL length limits and rate limits are useful stopgaps but do not eliminate the underlying library weakness — upgrade remains the ultimate fix.
Security posture and broader supply-chain considerations
This vulnerability is a reminder that tiny utilities — a single function that compiles a string to a regex — can carry disproportionate security weight when they sit in hot code paths. Mitigations to consider at the organizational level:- Maintain SBOMs for deployed artifacts and require automated checks for known CVEs during CI/CD.
- Use dependency pinning in lockfiles and have a process for coordinated dependency updates across microservices.
- Enforce policies for third-party code that will execute on the main thread in production (e.g., regex-heavy code, parsers).
- Consider multi-layer defenses: patching, edge protections, and runtime introspection are complementary.
Final assessment and recommendations
CVE-2024-45296 is high-severity in practice because it enables low-skill attackers to trigger high-impact availability failures against Node.js services that rely on path-to-regexp for routing. The attack surface is large due to the pervasiveness of the library in web frameworks and the commonality of the vulnerable route pattern.Actionable prioritized recommendations:
- Immediate (0–72 hours)
- Run a quick SBOM/dependency scan to identify vulnerable versions in prod/staging images and services.
- If vulnerable versions are present and an immediate upgrade is not possible, deploy URL length limits, strict rate limits, and WAF rules for public endpoints.
- Search your codebase for multi-parameter single-segment routes (patterns like
/:a-:b) and apply temporary rewriting or explicit safe regexes. - Short-term (1–2 weeks)
- Upgrade path-to-regexp to a patched maintenance release or to the safe major version and rebuild deployments.
- Test routing behavior for compatibility and performance regressions in staging.
- Audit all user-supplied regex templates and remove or validate dangerous ones.
- Medium-term (1–3 months)
- Add CI checks to detect and fail merges that introduce multi-parameter single-segment routes or unbounded custom regexes.
- Improve observability around route-match latency and event-loop lag; create alerts.
- Long-term
- Harden the supply chain: SBOMs, automated scanning, and enforced patch cycles.
- Consider architecture changes for critical services to move CPU‑intensive work off the event loop or into isolated worker processes.
CVE-2024-45296 is a practical lesson in how simple API conveniences (multiple parameters inside one URL segment) can inadvertently generate dangerous artifacts (backtracking-prone regular expressions). The good news is that upstream patches and version upgrades are available; the bad news is that the vulnerability is trivial to trigger from the network and straightforward to exploit at scale. The right combination of fast inventory, immediate compensating controls, and prioritized upgrades will reduce your exposure quickly and decisively.
Source: MSRC Security Update Guide - Microsoft Security Response Center
Similar threads
- Replies
- 0
- Views
- 7
- Article
- Replies
- 0
- Views
- 5
- Replies
- 0
- Views
- 1
- Replies
- 0
- Views
- 5
- Featured
- Article
- Replies
- 0
- Views
- 18