|
| 1 | +--- |
| 2 | +gem: addressable |
| 3 | +cve: 2026-35611 |
| 4 | +ghsa: h27x-rffw-24p4 |
| 5 | +url: https://github.com/sporkmonger/addressable/security/advisories/GHSA-h27x-rffw-24p4 |
| 6 | +title: Addressable has a Regular Expression Denial of Service in |
| 7 | + Addressable templates |
| 8 | +date: 2026-04-08 |
| 9 | +description: | |
| 10 | + ### Impact |
| 11 | +
|
| 12 | + Within the URI template implementation in Addressable, two classes |
| 13 | + of URI template generate regular expressions vulnerable to |
| 14 | + catastrophic backtracking: |
| 15 | +
|
| 16 | + 1. Templates using the `*` (explode) modifier with any expansion |
| 17 | + operator (e.g., `{foo*}`, `{+var*}`, `{#var*}`, `{/var*}`, |
| 18 | + `{.var*}`, `{;var*}`, `{?var*}`, `{&var*}`) generate patterns |
| 19 | + with nested unbounded quantifiers that are O(2^n) when matched |
| 20 | + against a maliciously crafted URI. |
| 21 | +
|
| 22 | + 2. Templates using multiple variables with the `+` or `#` operators |
| 23 | + (e.g., `{+v1,v2,v3}`) generate patterns with O(n^k) complexity |
| 24 | + due to the comma separator being within the matched character |
| 25 | + class, causing ambiguous backtracking across k variables. |
| 26 | +
|
| 27 | + When matched against a maliciously crafted URI, this can result |
| 28 | + in catastrophic backtracking and uncontrolled resource consumption, |
| 29 | + leading to denial of service. The first pattern was partially |
| 30 | + addressed in 2.8.10 for certain operator combinations. Both patterns |
| 31 | + are fully remediated in 2.9.0. |
| 32 | +
|
| 33 | + Users of the URI parsing capabilities in Addressable but not |
| 34 | + the URI template matching capabilities are unaffected. |
| 35 | +
|
| 36 | + ### Affected Versions |
| 37 | +
|
| 38 | + This vulnerability affects Addressable >= 2.3.0 (note: 2.3.0 and |
| 39 | + 2.3.1 were yanked; the earliest installable release is 2.3.2). |
| 40 | + It was partially fixed in version 2.8.10 and fully remediated in 2.9.0. |
| 41 | +
|
| 42 | + The vulnerability is more exploitable on MRI Ruby < 3.2 and on all |
| 43 | + versions of JRuby and TruffleRuby. MRI Ruby 3.2 and later ship with |
| 44 | + Onigmo 6.9, which introduces memoization that prevents catastrophic |
| 45 | + backtracking for the first class of template. JRuby and TruffleRuby |
| 46 | + do not implement equivalent memoization and remain vulnerable |
| 47 | + to all patterns. |
| 48 | +
|
| 49 | + This has been confirmed on the following runtimes: |
| 50 | +
|
| 51 | + | Runtime | Status | |
| 52 | + |--------------|--------| |
| 53 | + | MRI Ruby 2.6 | Vulnerable | |
| 54 | + | MRI Ruby 2.7 | Vulnerable | |
| 55 | + | MRI Ruby 3.0 | Vulnerable | |
| 56 | + | MRI Ruby 3.1 | Vulnerable | |
| 57 | + | MRI Ruby 3.2 | Partially vulnerable | |
| 58 | + | MRI Ruby 3.3 | Partially vulnerable | |
| 59 | + | MRI Ruby 3.4 | Partially vulnerable | |
| 60 | + | MRI Ruby 4.0 | Partially vulnerable | |
| 61 | + | JRuby 10.0 | Vulnerable | |
| 62 | + | TruffleRuby 21.2 | Vulnerable | |
| 63 | +
|
| 64 | + ### Workarounds |
| 65 | +
|
| 66 | + - **Upgrade to MRI Ruby 3.2 or later**, if your application does |
| 67 | + not use JRuby or TruffleRuby. The Onigmo memoization introduced |
| 68 | + in MRI Ruby 3.2 prevents catastrophic backtracking from nested |
| 69 | + unbounded quantifiers (pattern 1 above — templates using the `*` |
| 70 | + modifier). It does not reliably mitigate the O(n^k) multi-variable |
| 71 | + case (pattern 2), so upgrading Ruby alone may not be sufficient |
| 72 | + if your templates use `{+v1,v2,...}` or `{#v1,v2,...}` syntax. |
| 73 | +
|
| 74 | + - **Avoid using vulnerable template patterns** when matching |
| 75 | + user-supplied input on unpatched versions of the library: |
| 76 | +
|
| 77 | + - Templates using the `*` (explode) modifier: `{foo*}`, `{+var*}`, |
| 78 | + `{#var*}`, `{.var*}`, `{/var*}`, `{;var*}`, `{?var*}`, `{&var*}` |
| 79 | +
|
| 80 | + - Templates using multiple variables with the `+` or `#` |
| 81 | + operators: `{+v1,v2}`, `{#v1,v2,v3}`, etc. |
| 82 | +
|
| 83 | + - **Apply a short timeout** around any call to `Template#match` |
| 84 | + or `Template#extract` that processes user-supplied data. |
| 85 | +
|
| 86 | + ### Credits |
| 87 | +
|
| 88 | + Discovered in collaboration with @jamfish. |
| 89 | +
|
| 90 | + ### For more information |
| 91 | +
|
| 92 | + If you have any questions or comments about this advisory: |
| 93 | + * [Open an issue](https://github.com/sporkmonger/addressable/issues) |
| 94 | +cvss_v3: 7.5 |
| 95 | +unaffected_versions: |
| 96 | + - "< 2.3.0" |
| 97 | +patched_versions: |
| 98 | + - ">= 2.9.0" |
| 99 | +related: |
| 100 | + url: |
| 101 | + - https://nvd.nist.gov/vuln/detail/CVE-2026-35611 |
| 102 | + - https://github.com/sporkmonger/addressable/security/advisories/GHSA-h27x-rffw-24p4 |
| 103 | + - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS |
| 104 | + - https://cwe.mitre.org/data/definitions/1333.html |
| 105 | + - https://www.regular-expressions.info/catastrophic.html |
| 106 | + - https://github.com/advisories/GHSA-h27x-rffw-24p4 |
0 commit comments