CVE-2026-77299: Regexp2: Unbounded memory amplification via large `{m}` quantifier on a zero-width subexpression
Regexp2 is a feature-rich RegExp engine for Go. Prior to version 2.3.0, when regexp2 compiles and matches a pattern containing a large fixed-count quantifier applied to a zero-width subexpression — e.g. (?:){50000000} — the match engine executes the empty loop body m-1 times, pushing two integers onto the backtracking stack on every iteration. Because the parser accepts any repetition count up to math.MaxInt32 and the backtracking stack grows without bound, a pattern of fewer than 20 bytes matched against an empty input can force multi-gigabyte allocation and OOM-kill the process. MatchTimeout does not fully mitigate this because the memory is allocated faster than the 100 ms timeout clock can fire. This issue has been patched in version 2.3.0.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
regexp2to a version that resolves this vulnerability.Fixed in 2.3.0
Event History
Frequently Asked Questions
Who is realistically exposed to this issue?
Applications using Regexp2 before version 2.3.0 are exposed when an attacker can influence a pattern that the application compiles and matches. The triggering pattern can be fewer than 20 bytes and can be matched against empty input.
What does an attacker need to trigger the denial of service?
No privileges or user interaction are required. The attacker needs to supply or cause use of a pattern with a very large fixed-count quantifier on a zero-width subexpression, such as (?:){50000000}.
Does configuring MatchTimeout prevent exploitation?
No. MatchTimeout does not fully mitigate the issue because backtracking-stack memory can be allocated faster than the 100 ms timeout clock fires, potentially causing multi-gigabyte allocation and an OOM kill.
What is the remediation?
Upgrade Regexp2 to version 2.3.0, which includes the patch.