[16] path-to-regexp outputs backtracking regular expressions #395

Open
opened 2024-10-15 19:00:46 +01:00 by Helpdesk · 0 comments
Member

Package: path-to-regexp (npm)
Affected versions: < 0.1.10
Patched version: 0.1.10


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:

0.1.10
1.9.0
3.3.0
6.3.0
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
OWASP
Detailed blog post

Package: `path-to-regexp` (npm) Affected versions: `< 0.1.10` Patched version: `0.1.10` --- 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: 0.1.10 1.9.0 3.3.0 6.3.0 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 OWASP Detailed blog post
Helpdesk added the
type
alert
label 2024-10-15 19:00:46 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: External/card-drop#395
No description provided.