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

Uninitialized Use in ANGLE in Google Chrome prior to 149

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

This is a thief rifling through a room they already broke into, not a front-door lockpick

CVE-2026-11087 is an uninitialized memory use in ANGLE in Google Chrome fixed in 149.0.7827.53 and later. Public Chrome release notes list it as Medium and describe it simply as an ANGLE issue, while the CVE text adds the key real-world qualifier: the attacker must have already compromised the renderer process and then use a crafted HTML page to read potentially sensitive process memory.

Google's MEDIUM 6.5 label is fair in a vacuum, but for enterprise patch triage this lands lower. The decisive friction is the prerequisite: renderer compromise first. That means this is not a clean drive-by, not an edge-exposed service, and not a standalone enterprise entry point; it's a post-exploitation chain helper with confidentiality impact only.

"This is a post-compromise memory leak, not an initial-access bug—downgrade it and let auto-update do the work."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Win code execution inside the renderer first

The attacker needs a separate browser exploit, malicious extension, or equivalent primitive that already gives execution in Chrome's renderer sandbox. In practice this is the expensive step and the whole CVE depends on it. No public PoC for CVE-2026-11087 meaningfully removes that prerequisite.
Conditions required:
  • Attacker can get a target to load attacker-controlled web content
  • A separate renderer-compromise bug or implant is already available
  • Target is running Chrome prior to 149.0.7827.53
Where this breaks in practice:
  • This is post-initial-browser-compromise by definition
  • Modern Chrome hardening, site isolation, and renderer sandboxing raise the bar before this CVE is even reachable
  • No known public exploit chain specifically weaponizing this CVE
Detection/coverage: Version scanners can flag exposure, but they cannot prove exploitability because the core prerequisite is a separate renderer compromise.
STEP 02

Steer execution into ANGLE with crafted graphics content

Once inside the renderer, the attacker drives execution through ANGLE using crafted HTML/WebGL-style content to hit an uninitialized read condition. ANGLE is a graphics translation layer, so exploit reliability depends on the browser's rendering path, feature use, and platform behavior.
Conditions required:
  • Renderer code execution is already present
  • ANGLE-backed rendering path is reachable on the endpoint
  • The crafted page can exercise the vulnerable code path
Where this breaks in practice:
  • Hardware acceleration settings and platform differences can change reachability
  • Uninitialized reads are often noisier and less deterministic than write primitives
  • Enterprise browser policies may disable or constrain graphics features in some fleets
Detection/coverage: Expect little direct telemetry; browser crash spikes or unusual GPU/renderer instability may be the only weak signal.
STEP 03

Harvest leaked memory and exfiltrate it

If the read succeeds, the attacker can pull process-memory fragments that may contain tokens, URLs, pixels, or other residual data useful for chaining. This is confidentiality impact, not direct sandbox escape or code execution. The bug is most valuable as a support primitive inside a broader exploit chain.
Conditions required:
  • Useful secrets are present in readable memory
  • Attacker has a channel to exfiltrate recovered data
Where this breaks in practice:
  • Leaked bytes may be partial, stale, or operationally useless
  • Site isolation and process separation limit what valuable data co-resides
  • EDR/network controls may catch the exfiltration phase even if the read itself is silent
Detection/coverage: Detection is mostly indirect: unusual outbound requests from a browser process, suspicious follow-on authentication use, or incident evidence of a broader browser exploit chain.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known active exploitation found in the sources reviewed, and the user-supplied intel says KEV listed: No.
KEV statusNot listed in CISA's KEV catalog as of 2026-06-05.
Proof-of-concept availabilityNo public PoC located for this specific CVE. Chromium notes that bug details may stay restricted until most users are patched.
EPSS0.00035 (user-supplied), which is effectively near-floor exploit probability for the next 30 days.
CVSS and meaningCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N scores the *technical* impact of a web-triggered info leak, but it does not capture the crucial renderer-compromise prerequisite in the CVE text.
Affected versionsChrome prior to 149.0.7827.53. Chrome stable release notes show 149.0.7827.53 for Linux and 149.0.7827.53/54 for Windows/Mac on 2026-06-02.
Fixed versionsUpgrade to 149.0.7827.53 or later; in practice that means 149.0.7827.53+ on Linux and 149.0.7827.53/54+ on Windows/macOS depending on channel rollout.
Exposure and scanning realityThis is client software, not an internet-facing service. Shodan/Censys/GreyNoise-style exposure counts are largely not applicable; your real exposure surface is the count of endpoints running old Chrome builds.
Disclosure timelinePatch shipped publicly on 2026-06-02 in Chrome 149 stable release notes; the user-supplied disclosure date is 2026-06-04, which likely reflects CVE publication timing rather than first fix availability.
ReporterChrome release notes list this bug as reported by Google on 2026-04-07.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.9/10)

The single biggest reason this lands LOW is that exploitation requires the attacker to have already compromised Chrome's renderer process. That prerequisite makes this a narrow post-compromise data-leak primitive, not a realistic standalone enterprise intrusion path.

HIGH Version/fix metadata and vendor classification
MEDIUM Real-world exploitability downgrade based on the renderer-compromise prerequisite
MEDIUM No-public-PoC / no-active-exploitation assessment

Why this verdict

  • Major downward adjustment: requires renderer compromise first — attacker position is effectively *already inside the browser sandbox*, which implies a prior successful exploit stage or implant.
  • Population narrowing — every prerequisite compounds: web delivery + renderer compromise + ANGLE reachability + useful memory disclosure. That's a far smaller exposed population than Chrome's install base suggests.
  • Blast radius is limited — impact is confidentiality from process memory, not direct code execution, persistence, or sandbox escape on its own.
  • Threat intel is cold — no KEV listing, no public PoC found, and EPSS is effectively near zero.
  • Defenders usually get this one 'for free' — Chrome auto-update and routine browser hygiene remediate it without emergency patch motion.

Why not higher?

If this were reachable by an unauthenticated remote attacker without prior renderer compromise, or if there were active chains using it for sandbox escape, this would jump fast. But the CVE text itself narrows it to a secondary-stage primitive, and that is the real severity governor.

Why not lower?

It still matters because Chrome is ubiquitous and browser exploit chains are real. An information leak inside a compromised renderer can expose secrets or help stabilize a bigger chain, so this is not 'IGNORE'—it's just not worth front-of-queue emergency patching.

05 · Compensating Control

What to do — in priority order.

  1. Keep Chrome auto-update healthy — For a LOW browser client issue, the best compensating control is simply making sure enterprise Chrome update rings are functioning and stalled clients are rare. There is no mitigation SLA for LOW findings, so treat this as backlog hygiene and verify compliance during your normal browser maintenance cycle.
  2. Reduce risky web rendering surface — Where business-tolerable, restrict high-risk browser features with enterprise policy, especially on privileged admin workstations and VDI pools. This does not replace patching, but it reduces exploit-chain room while you roll routine updates; for LOW, do this opportunistically rather than as an emergency change.
  3. Watch for browser exploit-chain signals — Hunt for clusters of Chrome renderer/GPU crashes, odd child-process behavior, and suspicious browser-originated outbound traffic. This matters because the real danger here is not the leak alone but its role in a larger browser compromise chain; again, no LOW mitigation SLA, so fold this into standard detection engineering.
  4. Prioritize privileged user tiers — If you have to clean up in rings, start with admins, developers, and high-value research users who browse widely and hold useful tokens in memory. There is no formal LOW remediation deadline, but these cohorts are where a post-compromise browser leak has the highest value.
What doesn't work
  • A WAF does not help; this is a client-side browser bug, not a server-side HTTP parsing problem.
  • Perimeter network scanning does not measure exposure; Shodan-style visibility tells you almost nothing about unpatched Chrome on endpoints.
  • Relying on CVSS alone overstates urgency here because CVSS does not encode the already-compromised-renderer prerequisite called out in the CVE description.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or through your software-inventory automation. Invoke it as python3 chrome_cve_2026_11087_check.py to inspect common local Chrome installs, or python3 chrome_cve_2026_11087_check.py --version 149.0.7827.52 to check a version string from another tool; no admin privileges are required for the local checks.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# CVE-2026-11087 Chrome version verifier
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

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

FIXED = (149, 0, 7827, 53)


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


def version_str(v):
    return '.'.join(str(x) for x in v)


def compare(v1, v2):
    return (v1 > v2) - (v1 < v2)


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


def find_from_commands():
    candidates = [
        ['google-chrome', '--version'],
        ['google-chrome-stable', '--version'],
        ['chromium', '--version'],
        ['chromium-browser', '--version'],
        ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', '--version'],
    ]
    for cmd in candidates:
        out = run_cmd(cmd)
        v = parse_version(out)
        if v:
            return ('command', ' '.join(cmd), v)
    return None


def find_windows_file_version():
    if os.name != 'nt':
        return None
    paths = [
        os.path.join(os.environ.get('ProgramFiles', r'C:\Program Files'), 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(os.environ.get('ProgramFiles(x86)', r'C:\Program Files (x86)'), 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(os.environ.get('LocalAppData', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'),
    ]
    for p in paths:
        if p and os.path.exists(p):
            ps = [
                'powershell', '-NoProfile', '-Command',
                f"(Get-Item '{p}').VersionInfo.ProductVersion"
            ]
            out = run_cmd(ps)
            v = parse_version(out)
            if v:
                return ('file', p, v)
    return None


def find_macos_plist():
    plist = Path('/Applications/Google Chrome.app/Contents/Info.plist')
    if plist.exists():
        out = run_cmd(['/usr/bin/defaults', 'read', str(plist), 'KSVersion'])
        v = parse_version(out)
        if v:
            return ('plist', str(plist), v)
    return None


def find_linux_paths():
    paths = [
        '/opt/google/chrome/chrome',
        '/usr/bin/google-chrome',
        '/usr/bin/google-chrome-stable',
        '/snap/bin/chromium',
        '/usr/bin/chromium',
        '/usr/bin/chromium-browser',
    ]
    for p in paths:
        if os.path.exists(p):
            out = run_cmd([p, '--version'])
            v = parse_version(out)
            if v:
                return ('file', p, v)
    return None


def evaluate(v):
    if compare(v, FIXED) >= 0:
        print(f'PATCHED: Chrome version {version_str(v)} >= fixed {version_str(FIXED)}')
        sys.exit(0)
    else:
        print(f'VULNERABLE: Chrome version {version_str(v)} < fixed {version_str(FIXED)}')
        sys.exit(1)


def main():
    if len(sys.argv) == 3 and sys.argv[1] == '--version':
        v = parse_version(sys.argv[2])
        if not v:
            print('UNKNOWN: could not parse supplied version string')
            sys.exit(2)
        evaluate(v)

    found = find_from_commands()
    if not found and os.name == 'nt':
        found = find_windows_file_version()
    if not found and sys.platform == 'darwin':
        found = find_macos_plist()
    if not found and sys.platform.startswith('linux'):
        found = find_linux_paths()

    if not found:
        print('UNKNOWN: Google Chrome version could not be determined on this host')
        sys.exit(2)

    source_type, source_path, v = found
    # Commented source line for troubleshooting in automation logs
    # print(f'DEBUG: source={source_type} path={source_path} version={version_str(v)}')
    evaluate(v)


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

If you remember one thing.

TL;DR
Monday morning, do not stop the line for this one. Verify Chrome auto-update health, identify endpoints still below 149.0.7827.53, and clean them up in your normal browser maintenance flow; for a LOW verdict there is noisgate mitigation SLA and noisgate remediation SLA is effectively no SLA—treat as backlog hygiene. Put special attention on privileged user tiers and any hosts with broken browser updating, but this does not deserve emergency patch bandwidth unless you are already responding to a live browser-exploit incident.

Sources

  1. Chrome stable release 149
  2. Chrome releases archive 2026
  3. Chromium security page
  4. Chromium issue reference for CVE-2026-11087
  5. FIRST EPSS API documentation
  6. FIRST EPSS data and statistics
  7. CISA Known Exploited Vulnerabilities catalog
  8. SecurityWeek coverage of Chrome 149 release
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.