← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-10889 · CWE-125 · Disclosed 2026-06-04

Out of bounds read in ANGLE in Google Chrome prior to 149

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is the second lock on the vault door, not the front gate

CVE-2026-10889 is an out-of-bounds read in Chrome's ANGLE graphics layer affecting Chrome versions before 149.0.7827.53 on Linux, 149.0.7827.53/54 on Windows and macOS, with corresponding fixes also carried into Android 149.0.7827.59 and Extended Stable 148.0.7778.254 for Windows/macOS. The key detail is the exploitation model in your intel: the attacker must already have *compromised the renderer process* and then use this ANGLE bug to push beyond that boundary.

Vendor-style scoring overstates the fleet risk for defenders because it treats the bug's end-state impact more than its real-world prerequisite chain. In practice this is a *chain component* for a browser sandbox escape path: dangerous for targeted exploitation and red-team quality chains, but sharply constrained by the need for a separate renderer compromise first, the absence of KEV listing, the very low EPSS, and no visible public PoC for this specific CVE.

"Serious only as part of a Chrome exploit chain; by itself this is a post-renderer escape helper, not a Monday-morning fire drill."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Land malicious browser content

The attacker first needs a victim to render attacker-controlled web content, likely with GPU/graphics activity that exercises ANGLE. *Tool/reference:* a crafted HTML/WebGL page delivered via normal web browsing; no public weaponized PoC for this CVE was found. This step is broad in theory, but it does nothing on its own because CVE-2026-10889 is not described as direct web-to-host compromise.
Conditions required:
  • Victim browses attacker-controlled content
  • Chrome/Chromium build is older than the fixed version
  • ANGLE code path is reachable on the target platform
Where this breaks in practice:
  • This CVE is not described as a standalone renderer RCE
  • Enterprise browsers often auto-update on short cycles
  • GPU feature variation can make trigger reliability platform-specific
Detection/coverage: Web proxies and browser telemetry may show the visited domain, but scanners generally cannot detect exploit delivery from network traffic alone.
STEP 02

Obtain renderer compromise first

The decisive prerequisite is a separate vulnerability that gives code execution or equivalent control inside Chrome's renderer sandbox. *Tool/reference:* a companion renderer exploit in V8/Blink/media/etc.; this is an inference from Chromium's documented threat model for compromised renderers. Without this first-stage bug, CVE-2026-10889 is dead on arrival.
Conditions required:
  • Attacker has a distinct renderer exploit
  • That exploit works on the victim's exact Chrome build and platform
  • User interaction or visit flow reaches the exploit content
Where this breaks in practice:
  • Requires a second bug, not included in this CVE
  • Modern Chrome hardening, sandboxing, and site isolation raise chain complexity
  • Exploit reliability must survive version drift across a large enterprise fleet
Detection/coverage: EDR/browser crash telemetry may catch anomalous renderer crashes; vulnerability scanners do not prove this prerequisite.
STEP 03

Pivot from renderer into ANGLE/GPU attack surface

Once the renderer is compromised, the attacker can drive GPU-related IPC and crafted shader or rendering behavior toward ANGLE, which runs in a different process boundary than the renderer. *Tool/reference:* Chromium's GPU-process architecture and ANGLE attack surface. This is the point where CVE-2026-10889 becomes relevant as a sandbox-bypass helper.
Conditions required:
  • Renderer foothold already exists
  • Target uses the vulnerable ANGLE code path
  • IPC and rendering path reach the flawed memory access
Where this breaks in practice:
  • ANGLE/GPU paths differ by OS, driver, and hardware
  • Some enterprise environments reduce or virtualize GPU acceleration behavior
  • Out-of-bounds read is weaker than a write/use-after-free primitive
Detection/coverage: Limited direct scanner coverage; browser crash dumps and GPU process instability are the best defender signals.
STEP 04

Leak memory or assist a sandbox escape chain

An out-of-bounds read can disclose process memory and help defeat exploit mitigations, or in a broader chain contribute to escaping the renderer sandbox. *Tool/reference:* exploit-chain memory disclosure technique; no public exploit code for this CVE was identified. The impact can be severe in a targeted chain, but the blast radius is constrained because the attacker has already paid the price of renderer compromise.
Conditions required:
  • Bug is triggerable reliably after renderer compromise
  • Leaked memory is useful for the broader chain
  • Attacker can convert disclosure into meaningful post-sandbox gain
Where this breaks in practice:
  • Read-only primitive is less directly powerful than a write primitive
  • Additional chain work is typically required for stable host compromise
  • No evidence this CVE alone is being used at scale
Detection/coverage: Post-exploitation telemetry matters more than scanning. Look for unusual Chrome child-process crashes, GPU process faults, and suspicious browser-to-OS follow-on behavior in EDR.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence found that CVE-2026-10889 is exploited in the wild as of 2026-06-04; it is not in the CISA KEV catalog.
PoC availabilityNo public PoC or weaponized exploit specific to this CVE was found. The Chromium issue reference exists, but details remain restricted in the Chrome release bulletin.
EPSSProvided EPSS is 0.00068 (~0.068%), which is extremely low and consistent with a narrow, chain-dependent client-side bug rather than a broadly weaponized internet service flaw. Reference: FIRST EPSS and daily data/statistics.
KEV statusNot KEV-listed. That matters here because Chrome sandbox-escape-class bugs that are *actually* being used often get rapid ecosystem attention and, when confirmed, KEV treatment.
CVSS vector reality checkProvided vector CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H assumes a network-reachable client-side chain with scope change and full impact. The big real-world dampener is the hidden prerequisite: attacker already controls the renderer.
Affected versionsChrome prior to 149.0.7827.53; desktop stable bulletin lists fixed builds as Linux 149.0.7827.53 and Windows/macOS 149.0.7827.53/54.
Fixed versionsDesktop stable fix shipped 2026-06-02 in Chrome 149 stable. Android inherited the same security fixes in 149.0.7827.59, and Windows/macOS Extended Stable moved to 148.0.7778.254 on 2026-06-03.
Researcher / reporting sourceChrome stable bulletin says Reported by Google on 2026-05-14.
Scanning / exposure dataShodan/Censys-style internet exposure counts are not meaningful here because Chrome is an endpoint browser, not an internet-facing daemon. Exposure should be measured by fleet version inventory and browser update telemetry, not public attack-surface scans.
Disclosure dateYour provided disclosure date is 2026-06-04; the public stable desktop fix was released on 2026-06-02, with Android on 2026-06-02 and Extended Stable on 2026-06-03.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.6/10)

The single biggest reason this lands in MEDIUM is that exploitation requires a prior renderer compromise, which means the attacker already needs a separate Chrome exploit before this bug matters. That prerequisite crushes the exposed population and turns this from a fleet-wide emergency into a chained post-compromise hardening issue.

HIGH Version/fix mapping from Chrome release channels
MEDIUM Reassessed severity based on the renderer-compromise prerequisite
MEDIUM Inference that this functions primarily as a sandbox-escape/helper primitive rather than standalone compromise

Why this verdict

  • Major downward adjustment: exploitation requires a *compromised renderer process*, which implies the attacker already owns a separate Chrome bug and is now chaining this one post-initial-exploit.
  • Population is narrower than CVSS suggests: every target must be on a vulnerable Chrome build *and* on a platform/runtime path that exercises the vulnerable ANGLE/GPU behavior reliably.
  • Threat intel is cold: no KEV listing, no public PoC found, and the provided EPSS is extremely low, which argues against broad opportunistic weaponization.

Why not higher?

If this were reachable directly from a crafted page without the renderer-compromise prerequisite, it would stay in HIGH or worse. But a bug that only becomes useful *after* a separate browser exploit is materially less urgent for defenders managing patch queues across 10,000 hosts. Also, out-of-bounds read is usually a weaker primitive than direct write/UAF primitives for stable one-shot compromise.

Why not lower?

This still sits in the browser exploit-chain space, and Chrome is everywhere. If an attacker already has renderer code execution, a vulnerable cross-process graphics component is exactly the kind of second-stage primitive used to cross security boundaries, so this is not mere hygiene backlog.

05 · Compensating Control

What to do — in priority order.

  1. Force browser auto-update compliance — Measure and enforce Chrome version drift through your endpoint management stack so stale builds are quickly flushed from the fleet. Because this is a MEDIUM verdict there is no mitigation SLA; use this as risk reduction while driving to the 365-day remediation window, not as an emergency workaround.
  2. Keep Chrome sandbox and site isolation defaults intact — Do not relax browser hardening features for compatibility unless you have a tracked exception. The renderer-compromise prerequisite is the main friction keeping this CVE out of HIGH, so preserving the renderer boundary and process isolation is the most relevant defensive control while you patch.
  3. Inventory unmanaged Chromium variants — Hunt for portable Chrome, developer channels, embedded Chromium runtimes, and lagging VDI gold images that fall outside the standard update ring. Medium-severity client CVEs linger longest in those pockets, and there is no mitigation SLA — go straight to the 365-day remediation window for cleanup if no active exploitation appears.
  4. Watch for Chrome child-process crash clusters — Aggregate browser crash/telemetry from EDR, Windows Error Reporting, Linux coredumps, or macOS diagnostics to spot unusual renderer/GPU crash bursts tied to suspect sites. This will not prove exploitation, but it is one of the few defender-visible signals available for browser exploit-chain activity.
What doesn't work
  • A WAF or perimeter IPS does not materially help; this is client-side browser attack surface, not a server endpoint you can shield at the edge.
  • MFA is irrelevant to exploitability; it protects accounts, not the browser memory-safety path being abused.
  • Restarting Chrome without updating does not fix anything except transient state; the vulnerable code remains present until the patched build is installed.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or through your software inventory agent. Invoke with python3 check_chrome_cve_2026_10889.py on Windows/macOS/Linux; no admin rights are required if Chrome is installed in standard user- or system-level locations. The script checks common Chrome/Chromium paths, extracts the local version, and prints VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_chrome_cve_2026_10889.py
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

import os
import platform
import re
import shutil
import subprocess
import sys
from pathlib import Path

FIXED_MIN = (149, 0, 7827, 53)
EXT_STABLE_WIN_MAC = (148, 0, 7778, 254)
ANDROID_FIXED = (149, 0, 7827, 59)  # documented for reference; this script is desktop-focused


def parse_ver(s):
    m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', s or '')
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def ver_str(v):
    return '.'.join(str(x) for x in v) if v else 'UNKNOWN'


def run_cmd(cmd):
    try:
        p = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
        out = (p.stdout or '') + '\n' + (p.stderr or '')
        return p.returncode, out.strip()
    except Exception:
        return 99, ''


def candidate_commands():
    system = platform.system().lower()
    cmds = []

    if system == 'windows':
        local = os.environ.get('LOCALAPPDATA', '')
        pf = os.environ.get('PROGRAMFILES', '')
        pf86 = os.environ.get('PROGRAMFILES(X86)', '')
        candidates = [
            Path(local) / 'Google/Chrome/Application/chrome.exe',
            Path(pf) / 'Google/Chrome/Application/chrome.exe',
            Path(pf86) / 'Google/Chrome/Application/chrome.exe',
            Path(local) / 'Chromium/Application/chrome.exe',
            Path(pf) / 'Chromium/Application/chrome.exe',
            Path(pf86) / 'Chromium/Application/chrome.exe',
        ]
        for c in candidates:
            if c.exists():
                cmds.append([str(c), '--version'])

    elif system == 'darwin':
        candidates = [
            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
            str(Path.home() / 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
            '/Applications/Chromium.app/Contents/MacOS/Chromium',
            str(Path.home() / 'Applications/Chromium.app/Contents/MacOS/Chromium'),
        ]
        for c in candidates:
            if Path(c).exists():
                cmds.append([c, '--version'])

    else:
        for name in ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser', 'chrome']:
            p = shutil.which(name)
            if p:
                cmds.append([p, '--version'])

    return cmds


def classify(version_tuple):
    major = version_tuple[0]

    # Windows/macOS Extended Stable backport documented at 148.0.7778.254
    if major == 148 and version_tuple >= EXT_STABLE_WIN_MAC:
        return 'PATCHED'

    if version_tuple >= FIXED_MIN:
        return 'PATCHED'

    return 'VULNERABLE'


def main():
    cmds = candidate_commands()
    if not cmds:
        print('UNKNOWN - Chrome/Chromium executable not found in common locations')
        sys.exit(2)

    seen = []
    for cmd in cmds:
        rc, out = run_cmd(cmd)
        v = parse_ver(out)
        seen.append((cmd[0], v, out))
        if v:
            state = classify(v)
            print(f'{state} - {cmd[0]} version {ver_str(v)}')
            sys.exit(0 if state == 'PATCHED' else 1)

    print('UNKNOWN - Found browser executable(s) but could not parse version')
    for path, v, out in seen:
        print(f'Checked: {path} | Raw: {out}')
    sys.exit(2)


if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat this like a Chrome zero-day fire drill unless fresh exploitation evidence emerges. Fold it into your normal browser servicing ring: validate fleet inventory for Chrome/Chromium versions below the fixed builds, keep sandbox/site-isolation defaults intact where patch lag exists, and drive updates under the noisgate mitigation SLA rule that there is no mitigation SLA — go straight to the 365-day remediation window for a MEDIUM verdict; the actual browser patch should land within the noisgate remediation SLA of 365 days, though most enterprises should realistically clear mainstream Chrome within the next regular monthly client-update cycle, not at year-end.

Sources

  1. Chrome Releases - Stable Channel Update for Desktop (2026-06-02)
  2. Chrome Releases - Extended Stable Updates for Desktop (2026-06-03)
  3. Chrome Releases - Chrome for Android Update (2026-06-02)
  4. Chromium Security - Site Isolation
  5. Chromium Security - chrome://sandbox Diagnostics for Windows
  6. Chromium design doc - GPU accelerated compositing in Chrome
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.