This is a peephole in Chrome’s graphics plumbing, not a battering ram through the front door
CVE-2026-10994 is an *uninitialized use* bug in Chrome’s ANGLE graphics layer, meaning a malicious page can potentially coax the browser into exposing stale process memory that should never be surfaced to web content. The affected range is Chrome before 149.0.7827.53; Google’s desktop stable notes show fixes in 149.0.7827.53 for Linux and 149.0.7827.53/.54 for Windows and macOS.
Google’s MEDIUM / 6.5 rating is basically fair. The bug is remotely triggerable and Chrome is everywhere, but the real-world attack still needs a user to open attacker-controlled content, the impact is *information disclosure rather than code execution*, and the threat telemetry is cold: no KEV listing, no vendor note of in-the-wild exploitation, and an EPSS of 0.00035.
4 steps from start to impact.
Land the victim on a malicious page
- Victim uses vulnerable Chrome
- Victim opens attacker-controlled or attacker-influenced content
- Normal web browsing is allowed
- Requires user interaction (
UI:R) - Email gateway, web filtering, or safe browsing controls may stop delivery
- Attack dies if the browser already updated itself
Exercise the ANGLE rendering path
- ANGLE-backed rendering path is reachable on the target platform
- Attacker knows how to trigger the buggy code path
- Chrome mitigation behavior does not fully mask the leak
- Bug details are still restricted in Google’s release notes
- Browser memory-corruption primitives are notoriously finicky across GPU/driver/platform combinations
- Enterprise GPU settings, rendering differences, and browser hardening reduce exploit reliability
Turn stale memory into usable disclosure
- Leaked bytes are attacker-observable
- Useful secrets happen to be resident in reachable memory
- Leak quality is high enough to separate signal from noise
- Information leaks are often noisy and low-precision
- Chrome site isolation and process boundaries sharply reduce the odds of getting high-value cross-origin secrets in one shot
- Many leaks are only useful when chained with another bug
Exfiltrate the data
- Victim browser can make outbound web requests
- The attacker successfully parsed valuable data from the leak
- DLP is weak against small encrypted web beacons but the actual amount of useful data may be tiny
- The leak may produce nothing actionable on most runs
The supporting signals.
| In-the-wild status | No current exploitation signal found. CISA KEV does not list CVE-2026-10994, and Google’s stable release note does not include the usual language used when it knows of active exploitation. |
|---|---|
| Public PoC availability | No public PoC found in browsed sources as of 2026-06-05. Google explicitly says bug details may stay restricted until most users are patched, which is normal for fresh Chrome memory-safety fixes. |
| EPSS | 0.00035 from supplied intel; that is effectively background noise, not an exploitation wave. Percentile was not available in the authoritative browsed sources. |
| KEV status | Not KEV-listed as checked against CISA’s Known Exploited Vulnerabilities Catalog on 2026-06-05. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N = remote reachability, no auth, but user interaction required and confidentiality-only impact. |
| Affected versions | Chrome prior to 149.0.7827.53. Google’s desktop stable bulletin maps the fixed builds to 149.0.7827.53 (Linux) and 149.0.7827.53/.54 (Windows/macOS). |
| Fixed versions | Upgrade to 149.0.7827.53+ on Linux and 149.0.7827.53/.54+ on Windows/macOS. I found no distro-specific Chromium backport evidence in browsed sources, so treat vendor Chrome versioning as authoritative here. |
| Exposure reality | Shodan/Censys-style internet counts are the wrong lens. This is a client-side browser issue, so exposure is your endpoint fleet size, not a server listening on the internet. |
| Disclosure timeline | There is a date mismatch worth noting: Google shipped the fixed desktop stable build on 2026-06-02, the early stable build was visible on 2026-05-29, and third-party/public alerting appeared on 2026-06-05. Your supplied CVE intel lists 2026-06-04 as disclosure. |
| Reporter | Reported by Mufeed VH from Winfunc Research on 2026-04-21, per Google’s Chrome stable release note. |
noisgate verdict.
The decisive factor is that this is a user-driven confidentiality leak, not a pre-auth internet-facing server compromise or an RCE. Chrome’s huge footprint keeps it relevant, but the absence of exploitation evidence and the need to convert a fragile renderer leak into useful data keep it squarely in the middle bucket.
Why this verdict
- User interaction drags it down: the attacker must get a victim onto malicious content, which implies phishing/malvertising success rather than straight unauthenticated exploitation of an exposed service.
- The impact is leak-only: the vendor vector is confidentiality-only with no integrity or availability loss, so this is not the kind of bug that independently takes over endpoints.
- Threat intel is cold: no KEV, no public PoC found, and EPSS at 0.00035 all argue against urgent exploitation pressure.
- Browser ubiquity keeps it from falling to LOW: Chrome is everywhere in enterprise fleets, and browsers routinely hold session material and sensitive page data, so even a mere info leak deserves patch coverage.
Why not higher?
There is no present evidence of broad in-the-wild use, and the bug does not hand the attacker code execution on its own. In practice, an ANGLE memory-disclosure primitive still has to survive browser mitigations, platform variance, and the problem of turning leaked bytes into something valuable.
Why not lower?
This is still a remote web-triggered browser bug in a massively deployed product. Even when the standalone impact is limited to disclosure, browsers sit next to SSO sessions, internal apps, and sensitive content, so dismissing it as backlog-only would be too relaxed.
What to do — in priority order.
- Enforce Chrome auto-update — Make sure enterprise policy, MDM, or endpoint tooling is not pinning users below the fixed build. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but because Chrome updates are low-friction this should ride your normal desktop update control immediately.
- Audit version pinning and deferred channels — Find OUs, rings, VDI images, kiosk builds, and exception groups stuck on older Chrome milestones. There is no mitigation SLA — go straight to the 365-day remediation window, and this check is how you keep one stale ring from quietly carrying the risk for months.
- Keep browser and GPU sandboxing intact — Do not relax Chrome hardening or renderer isolation to work around application issues unless you absolutely must. There is no mitigation SLA — go straight to the 365-day remediation window, and intact sandboxing is your best damage-limiter if a browser info leak is ever chained.
- Use web filtering against newly seen domains — This will not fix the bug, but it does reduce the chance of victims reaching attacker-controlled pages that try to exercise it. There is no mitigation SLA — go straight to the 365-day remediation window; treat this as exposure reduction, not a substitute for the fixed build.
- A WAF does not materially help because the attack executes in the *client browser* after the user loads malicious content.
- MFA does not stop the vulnerability from leaking renderer memory; it only reduces the value of some stolen session artifacts.
- External network vuln scanning is mostly useless here because there is no server-side service banner to probe; you need endpoint/browser inventory instead.
Crowdsourced verification payload.
Run this on the target endpoint or through your EDR/RMM agent. Invoke it as python3 check_chrome_cve_2026_10994.py on macOS/Linux or py check_chrome_cve_2026_10994.py on Windows; no administrator rights are normally required, though Windows registry access to machine-wide install keys must be allowed.
#!/usr/bin/env python3
# check_chrome_cve_2026_10994.py
# Determine whether a local Google Chrome installation is vulnerable to CVE-2026-10994.
# Fixed baseline used here: 149.0.7827.53 (Linux) and 149.0.7827.53/.54 (Windows/macOS).
# Any version < 149.0.7827.53 is treated as VULNERABLE.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import platform
import re
import shutil
import subprocess
import sys
FIXED = (149, 0, 7827, 53)
VERSION_RE = re.compile(r'(\d+)\.(\d+)\.(\d+)\.(\d+)')
def parse_version(text):
if not text:
return None
m = VERSION_RE.search(text)
if not m:
return None
return tuple(int(x) for x in m.groups())
def cmp_ver(a, b):
return (a > b) - (a < b)
def read_cmd(path):
try:
out = subprocess.check_output([path, '--version'], stderr=subprocess.STDOUT, text=True, timeout=5)
return out.strip()
except Exception:
return None
def check_windows_registry():
versions = []
try:
import winreg # type: ignore
except Exception:
return versions
roots = [
(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Google\Chrome\BLBeacon'),
(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Google\Chrome\BLBeacon'),
(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Google\Chrome\BLBeacon'),
]
for hive, keypath in roots:
try:
with winreg.OpenKey(hive, keypath) as k:
val, _ = winreg.QueryValueEx(k, 'version')
v = parse_version(str(val))
if v:
versions.append((keypath, v))
except Exception:
pass
return versions
def check_windows_files():
candidates = [
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'),
]
versions = []
for path in candidates:
if path and os.path.exists(path):
out = read_cmd(path)
v = parse_version(out)
if v:
versions.append((path, v))
return versions
def check_macos():
candidates = [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
]
versions = []
for path in candidates:
if os.path.exists(path):
out = read_cmd(path)
v = parse_version(out)
if v:
versions.append((path, v))
return versions
def check_linux():
names = ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser']
versions = []
for name in names:
path = shutil.which(name)
if path:
out = read_cmd(path)
v = parse_version(out)
if v:
versions.append((path, v))
return versions
def fmt(v):
return '.'.join(str(x) for x in v)
def main():
system = platform.system().lower()
found = []
if system == 'windows':
found.extend(check_windows_registry())
found.extend(check_windows_files())
elif system == 'darwin':
found.extend(check_macos())
elif system == 'linux':
found.extend(check_linux())
else:
print(f'UNKNOWN - Unsupported platform: {platform.system()}')
sys.exit(2)
# De-duplicate by (location, version)
uniq = []
seen = set()
for item in found:
if item not in seen:
uniq.append(item)
seen.add(item)
found = uniq
if not found:
print('UNKNOWN - Google Chrome/Chromium not found or version unreadable')
sys.exit(2)
vulnerable = []
patched = []
for loc, ver in found:
if cmp_ver(ver, FIXED) < 0:
vulnerable.append((loc, ver))
else:
patched.append((loc, ver))
if vulnerable:
print('VULNERABLE - Found browser version(s) below 149.0.7827.53:')
for loc, ver in vulnerable:
print(f' {loc}: {fmt(ver)}')
if patched:
print('Also found patched version(s):')
for loc, ver in patched:
print(f' {loc}: {fmt(ver)}')
sys.exit(1)
print('PATCHED - All discovered browser version(s) are >= 149.0.7827.53:')
for loc, ver in patched:
print(f' {loc}: {fmt(ver)}')
sys.exit(0)
if __name__ == '__main__':
main()
If you remember one thing.
Sources
- Google Chrome Releases - Stable Channel Update for Desktop (Chrome 149)
- Google Chrome Releases - Early Stable Updates
- VulDB entry for CVE-2026-10994
- CISA Known Exploited Vulnerabilities Catalog
- FIRST EPSS API documentation
- FIRST EPSS model overview
- GovCERT.HK alert for Chrome 149 vulnerabilities
- Chrome Enterprise release channel guidance
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.