GHSA-gg6h-894w-4m9c - RE2JS: Quadratic-time denial of service in re2js lookbehind matching
### Summary
Using the opt-in `LOOKBEHINDS` flag together with any repeated-matching API
(`matcher().find()` in a loop, `matchAll()`, `split()`, `matcher().replaceAll()`)
causes quadratic-time (ฮ(nยฒ)) matching, contradicting the library's own
"linear time matching" guarantee. A single call with a 16,000-character input
takes **36.7โ38.7 seconds of CPU**.
### Description
#### Root cause
In `build/index.cjs`, `Machine.match`:
```js
let currentPos = this.prog.numLb > 0 ? 0 : pos; // ~line 1907
...
if (this.ncap === 0 && this.matched) break; // ~line 1953
```
Any pattern containing a lookbehind sets `prog.numLb > 0`, which forces the
scan to **always restart at offset 0**, regardless of the requested start
position โ the lookbehind automaton is re-seeded and the whole input is
re-walked on every single `find()` call. The early-exit optimization that
would otherwise stop at the first match only fires when `ncap === 0`, but
every `Matcher`-based API (`find`/`matchAll`/`split`/`replaceAll`) always
requests `ncap = 2` (one capture group slot) **even for a captureless
lookbehind pattern** โ so the early exit never triggers through those APIs,
and the scan continues to the end of the input on every find.
A find-loop over *k* matches in an *n*-character string therefore costs
*k* ร ฮ(*n*); for dense matches *k* โ *n*, giving **ฮ(nยฒ)** total.
#### Isolating control
Identical find-loop, identical input sizes, same 2-character literal pattern
*shape* โ but **without** the `LOOKBEHINDS` flag:
| n | with `LOOKBEHINDS` (lookbehind pattern) | without (plain literal) | native JS `RegExp` lookbehind |
|---|---|---|---|
| 2,000 | 204โ228 ms | 3 ms | 0 ms |
| 4,000 | 877โ899 ms | 4 ms | 0 ms |
| 8,000 | 5,746โ6,599 ms | 7 ms | 1 ms |
| 16,000 | 36,667โ38,732 ms | 6 ms | 1 ms |
This isolates the lookbehind machinery itself โ not pattern length, not
match density in the abstract โ as the exact and sole cause.
#### Impact
- `re2js`'s entire value proposition is being an
HIGH
Severity & confidence
Source severityhigh
Platform severityhigh
Confidencehigh
Exploitationunknown
CVSS7.5
Affected
Vendorsre2js
Productsre2js
Reporting sources (2)
GitHub Security Advisories
NIST NVD - National Vulnerability Database
Timeline & provenance
Published2026-10-28T21:10:01
Last updated2026-10-31T18:01:25
Ingested2026-10-28T21:27:23
FreshnessNEAR-REAL-TIME
Threat typeadvisory
Recommended action
Review the advisory and upgrade affected packages to the first patched version.
Next steps
- Identify affected systems in your environment.
- Apply the vendor patch or mitigation guidance.
- Review logs for indicators described in the advisory.
- Follow the affected vendor/product to track updates.
Confidence explanation
Reported by a government or cert-grade source (CISA, NCSC, NVD, ENISA, MSRC).
Source type: vendor ยท Original: GitHub Security Advisories