CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

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

mediumCVSS 5.7CVE-2026-67550
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: // 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: // 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

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
medium — CVSS 5.7
Published
2026-07-31
Last updated
2026-07-31
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-ff84-5f28-78qj

Exploitation outlook

EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-67550coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories