re2

Ecosystem: npm

Downloads:

Vulnerabilities from the last (months)
  • 0CriticalAffects 0 versions
  • 0HighAffects 0 versions
  • 0MediumAffects 0 versions
  • 4ModerateAffects 4 versions
  • 0LowAffects 0 versions
Severity distribution (all time)
4vulnerabilities
  • Critical0 (0.0%)
  • High0 (0.0%)
  • Medium0 (0.0%)
  • Moderate4 (100.0%)
  • Low0 (0.0%)

Monthly breakdown

  • Critical
  • High
  • Medium
  • Moderate
  • Low
  • 2 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 2
    • Low: 0
  • 2 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 2
    • Low: 0

Vulnerabilities (4)

Known vulnerabilities affecting re2, based on data from OSV.

Vulnerabilities affecting re2
IDSeveritySummaryAffected versionsPublishedSource
GHSA-8hcv-x26h-mcgpModeratenode-re2: String.prototype.replace(re2, template) aborts the Node process (uncatchable ToLocalChecked on empty MaybeLocal) when the result exceeds V8's max string length## Description `WrappedRE2::Replace` builds the replacement result and hands it to V8 with `.ToLocalChecked()` **without checking for the empty `MaybeLocal`** that V8 returns when the string/buffer exceeds its maximum length: `lib/replace.cc` (v1.24.1): ```cpp // L553 — Buffer return path info.GetReturnValue().Set(Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked()); // L556 — String return path info.GetReturnValue().Set(Nan::New(result).ToLocalChecked()); ``` When a global replace uses an output-amplifying template — `$'` (text after the match) or `` $` `` (text before the match
  • < 1.25.1
GitHub (opens in a new tab)
GHSA-j4r3-hg7j-8chgModeratenode-re2: Out-of-bounds heap read in `replace`/`split` via a `Buffer` ending in a truncated multi-byte UTF-8 character → adjacent heap memory disclosed to JavaScript## Summary `re2` infers a character's byte length from its UTF-8 lead byte alone, with no bound on the bytes actually remaining in the input. `Buffer` arguments reach the native layer verbatim — only strings are re-encoded into well-formed UTF-8 — so a `Buffer` whose last byte is a multi-byte lead promises continuation bytes that are not there, and the result builders read up to 3 bytes past the end of the buffer. In `replace()` and `split()` those bytes are copied into the returned `Buffer`, disclosing adjacent heap memory to JavaScript. The trigger is deterministic and requires no special h
  • < 1.26.1
GitHub (opens in a new tab)
GHSA-6hxr-mr5r-9836Moderatere2: Global `String.prototype.match` with an empty-matchable pattern never advances → infinite loop with unbounded native memory growth (DoS)## Summary `String.prototype.match` with a **global** `RE2` collects all matches in a native loop that advances the cursor by the match length. A **zero-width (empty) match** has length 0, so the cursor never advances: the same empty match is found forever and appended to an ever-growing native vector. Any pattern that can match the empty string (`a*`, `b?`, `x{0,3}`, `(a)|`, `(?:)`, …) therefore causes an infinite loop with unbounded memory growth. The call is synchronous native code, so it blocks the entire event loop and cannot be interrupted by `try/catch`, `AbortController`, `--max-old-s
  • < 1.25.2
GitHub (opens in a new tab)
GHSA-ff84-5f28-78qjModeratere2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex` on a non-ASCII subject → uncatchable process crash (DoS)## Summary `re2` validates the user-settable `lastIndex` against the subject's **UTF-8 byte length** but then uses it as a **UTF-16 code-unit count** to walk the subject buffer, with no bounds check. For any non-ASCII subject, the byte length is larger than the true character count, so a `lastIndex` between those two values passes validation while pointing past the end of the buffer. The subsequent walk reads out of bounds. With a large subject the read marches into unmapped memory and the process dies with **SIGABRT/SIGSEGV** — an uncatchable crash (`try/catch` cannot stop it), i.e. a denial
  • < 1.25.2
GitHub (opens in a new tab)
  • GHSA-8hcv-x26h-mcgpModerate
    node-re2: String.prototype.replace(re2, template) aborts the Node process (uncatchable ToLocalChecked on empty MaybeLocal) when the result exceeds V8's max string length
    • < 1.25.1

    ## Description `WrappedRE2::Replace` builds the replacement result and hands it to V8 with `.ToLocalChecked()` **without checking for the empty `MaybeLocal`** that V8 returns when the string/buffer exceeds its maximum length: `lib/replace.cc` (v1.24.1): ```cpp // L553 — Buffer return path info.GetReturnValue().Set(Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked()); // L556 — String return path info.GetReturnValue().Set(Nan::New(result).ToLocalChecked()); ``` When a global replace uses an output-amplifying template — `$'` (text after the match) or `` $` `` (text before the match

    CVE: CVE-2026-71430

  • GHSA-j4r3-hg7j-8chgModerate
    node-re2: Out-of-bounds heap read in `replace`/`split` via a `Buffer` ending in a truncated multi-byte UTF-8 character → adjacent heap memory disclosed to JavaScript
    • < 1.26.1

    ## Summary `re2` infers a character's byte length from its UTF-8 lead byte alone, with no bound on the bytes actually remaining in the input. `Buffer` arguments reach the native layer verbatim — only strings are re-encoded into well-formed UTF-8 — so a `Buffer` whose last byte is a multi-byte lead promises continuation bytes that are not there, and the result builders read up to 3 bytes past the end of the buffer. In `replace()` and `split()` those bytes are copied into the returned `Buffer`, disclosing adjacent heap memory to JavaScript. The trigger is deterministic and requires no special h

    CVE: CVE-2026-71498

  • GHSA-6hxr-mr5r-9836Moderate
    re2: Global `String.prototype.match` with an empty-matchable pattern never advances → infinite loop with unbounded native memory growth (DoS)
    • < 1.25.2

    ## Summary `String.prototype.match` with a **global** `RE2` collects all matches in a native loop that advances the cursor by the match length. A **zero-width (empty) match** has length 0, so the cursor never advances: the same empty match is found forever and appended to an ever-growing native vector. Any pattern that can match the empty string (`a*`, `b?`, `x{0,3}`, `(a)|`, `(?:)`, …) therefore causes an infinite loop with unbounded memory growth. The call is synchronous native code, so it blocks the entire event loop and cannot be interrupted by `try/catch`, `AbortController`, `--max-old-s

    CVE: CVE-2026-68499

  • GHSA-ff84-5f28-78qjModerate
    re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex` on a non-ASCII subject → uncatchable process crash (DoS)
    • < 1.25.2

    ## Summary `re2` validates the user-settable `lastIndex` against the subject's **UTF-8 byte length** but then uses it as a **UTF-16 code-unit count** to walk the subject buffer, with no bounds check. For any non-ASCII subject, the byte length is larger than the true character count, so a `lastIndex` between those two values passes validation while pointing past the end of the buffer. The subsequent walk reads out of bounds. With a large subject the read marches into unmapped memory and the process dies with **SIGABRT/SIGSEGV** — an uncatchable crash (`try/catch` cannot stop it), i.e. a denial

    CVE: CVE-2026-67550

Showing 1-4 of 4 vulnerabilities