Ecosyste.ms: Advisories

An open API service providing security vulnerability metadata for many open source software ecosystems.

Security Advisories: GSA_kwCzR0hTQS05d3Y2LTg2djItNTk4as4AA_Yf

path-to-regexp outputs backtracking regular expressions

Impact

A bad regular expression is generated any time you have two parameters within a single segment, separated by something that is not a period (.). For example, /:a-:b.

Patches

For users of 0.1, upgrade to 0.1.10. All other users should upgrade to 8.0.0.

These versions add backtrack protection when a custom regex pattern is not provided:

They do not protect against vulnerable user supplied capture groups. Protecting against explicit user patterns is out of scope for old versions and not considered a vulnerability.

Version 7.1.0 can enable strict: true and get an error when the regular expression might be bad.

Version 8.0.0 removes the features that can cause a ReDoS.

Workarounds

All versions can be patched by providing a custom regular expression for parameters after the first in a single segment. As long as the custom regular expression does not match the text before the parameter, you will be safe. For example, change /:a-:b to /:a-:b([^-/]+).

If paths cannot be rewritten and versions cannot be upgraded, another alternative is to limit the URL length. For example, halving the attack string improves performance by 4x faster.

Details

Using /:a-:b will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/. This can be exploited by a path such as /a${'-a'.repeat(8_000)}/a. OWASP has a good example of why this occurs, but the TL;DR is the /a at the end ensures this route would never match but due to naive backtracking it will still attempt every combination of the :a-:b on the repeated 8,000 -a.

Because JavaScript is single threaded and regex matching runs on the main thread, poor performance will block the event loop and can lead to a DoS. In local benchmarks, exploiting the unsafe regex will result in performance that is over 1000x worse than the safe regex. In a more realistic environment using Express v4 and 10 concurrent connections, this translated to average latency of ~600ms vs 1ms.

References

Permalink: https://github.com/advisories/GHSA-9wv6-86v2-598j
JSON: https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS05d3Y2LTg2djItNTk4as4AA_Yf
Source: GitHub Advisory Database
Origin: Unspecified
Severity: High
Classification: General
Published: 2 months ago
Updated: 2 months ago


CVSS Score: 7.5
CVSS vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Identifiers: GHSA-9wv6-86v2-598j, CVE-2024-45296
References: Repository: https://github.com/pillarjs/path-to-regexp
Blast Radius: 49.7

Affected Packages

npm:path-to-regexp
Dependent packages: 6,683
Dependent repositories: 4,298,330
Downloads: 267,027,225 last month
Affected Version Ranges: >= 4.0.0, < 6.3.0, >= 7.0.0, < 8.0.0, >= 2.0.0, < 3.3.0, >= 0.2.0, < 1.9.0, < 0.1.10
Fixed in: 6.3.0, 8.0.0, 3.3.0, 1.9.0, 0.1.10
All affected versions: 0.0.1, 0.0.2, 0.1.0, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.1.9, 0.2.0, 0.2.1, 0.2.2, 0.2.3, 0.2.4, 0.2.5, 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.1.0, 1.1.1, 1.2.0, 1.2.1, 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.5.2, 1.5.3, 1.6.0, 1.7.0, 1.8.0, 2.0.0, 2.1.0, 2.2.0, 2.2.1, 2.3.0, 2.4.0, 3.0.0, 3.1.0, 3.2.0, 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 5.0.0, 6.0.0, 6.1.0, 6.2.0, 6.2.1, 6.2.2, 7.0.0, 7.1.0, 7.2.0
All unaffected versions: 0.1.10, 0.1.11, 1.9.0, 3.3.0, 6.3.0, 8.0.0, 8.1.0, 8.2.0