This is a peephole drilled through Chrome’s same-origin wall, not a front door kicked off its hinges
CVE-2026-10985 is an out-of-bounds read in Chrome’s Skia graphics stack that affects Google Chrome versions prior to 149.0.7827.53. A malicious site can use crafted HTML to trigger the bug and leak data that should stay isolated by browser origin boundaries, turning a page view into cross-origin information disclosure rather than full browser compromise.
The vendor-style 6.5 MEDIUM label is mostly fair for enterprise patch triage. Chrome is everywhere, so the reachable population is huge, but the attacker still needs the user to render hostile content and the outcome is confidentiality loss only; there is no published claim here of code execution, sandbox escape, or system takeover. That keeps this out of emergency territory even though Chrome’s internal bug label calls the issue High.
4 steps from start to impact.
Land the victim on attacker-controlled HTML
- Target is running Chrome earlier than
149.0.7827.53 - User interaction occurs: click, redirect, ad-tech delivery, or embedded content render
- Attacker can host or inject crafted web content
- Requires user interaction; this is not scan-and-own
- Enterprise web filtering, ad blocking, and browser isolation can reduce lure success
- Short browser update cadences shrink the exploitable window fast
Trigger the Skia out-of-bounds read
- Renderer reaches the vulnerable Skia code path
- Exploit content is stable enough across the victim’s platform/build
- Browser exploitation reliability is sensitive to exact build, platform, and memory layout
- The underlying Chromium issue is not publicly readable from the available source set, which suggests lower public exploit maturity right now
Harvest cross-origin data from browser memory
- Victim has useful browser-resident secrets or active authenticated sessions
- Leaked bytes are sufficient to recover tokens, page fragments, or sensitive cross-origin content
- Impact depends heavily on what the victim is signed into at that moment
- This is confidentiality-only in the published record; no integrity or availability impact is claimed
- Blast radius is usually one browser session at a time
Operationalize stolen session data
- Leaked data contains actionable secrets or sensitive internal content
- Attacker can use the data before tokens expire or sessions rotate
- Modern session binding, short-lived tokens, and MFA-backed reauth can limit replay value
- Many browser leaks produce partial data, not turnkey account takeover
The supporting signals.
| In-the-wild status | No authoritative exploitation evidence found as of 2026-06-05. The CVE is not in CISA KEV, and the source set reviewed did not show Google calling this a zero-day. |
|---|---|
| PoC availability | No public GitHub or researcher PoC located in web review as of 2026-06-05. The referenced Chromium issue exists, but the accessible issue page did not expose technical details without sign-in. |
| EPSS | 0.00035 from the user intel, which is extremely low in absolute terms; that aligns with low near-term exploitation pressure rather than internet-scale abuse. |
| KEV status | Not KEV-listed as of 2026-06-05. That materially lowers urgency versus browser bugs already showing real-world abuse. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N maps to drive-by reachable, no auth, user interaction required, confidentiality-only impact. |
| Affected versions | Google Chrome prior to 149.0.7827.53 per NVD and the advisory chain. GovCERT also summarizes the affected set as versions before 149.0.7827.53. |
| Fixed versions | Patch floor is 149.0.7827.53. Google’s release note URL indicates the stable desktop rollout at 149.0.7827.53/.54; for conservative fleet triage, treat anything below 149.0.7827.53 as vulnerable. |
| Exposure and scanning reality | This is not an internet-scannable service; Shodan/Censys/FOFA-style exposure counts are not a useful prioritization input here. The real exposure metric is how many endpoints are still on old Chrome builds. |
| Disclosure date | 2026-06-04 in NVD quick info, with modification on 2026-06-05 after CISA-ADP scoring. |
| Reporter / provenance | The CNA/source is Chrome. No public researcher credit was recoverable from the accessible source set, so assume the detail remains limited at this stage. |
noisgate verdict.
The decisive factor is that the exploit chain still requires user-driven rendering of attacker content and only delivers information disclosure, not code execution or sandbox escape. Chrome’s massive footprint keeps this relevant, but the lack of active exploitation evidence and the confidentiality-only outcome keep it in MEDIUM.
Why this verdict
- Start from the browser baseline: Chrome is near-ubiquitous in enterprise fleets, so any remotely triggerable browser bug deserves initial attention even before exploitation evidence shows up.
- User interaction is a real brake: the attacker must get the victim to render crafted content, which implies phishing, malvertising, or content injection rather than unauthenticated internet-wide exploitation.
- Impact is bounded to confidentiality: the published record claims cross-origin data leakage, not arbitrary code execution, persistence, lateral movement, or OS compromise; that sharply limits blast radius per event.
- No live-fire signal: no KEV entry, no zero-day language in the reviewed sources, and a very low EPSS all push this down from emergency patch status.
- Population is wide but exploit surface is session-dependent: the bug matters most when users are simultaneously authenticated to valuable internal or SaaS apps, which is common enough to matter but not enough to justify a HIGH without stronger exploitation evidence.
Why not higher?
A HIGH would need either an exploitation amplifier or a bigger blast radius: active attacks, public exploit tooling, code execution, sandbox escape, or a practical path to broad credential theft at scale. We do not have that here from the reviewed sources; what we have is a browser info leak that still depends on a lure and on valuable victim browsing state.
Why not lower?
This is not backlog lint. It is remotely reachable through normal web browsing, requires no authentication, and targets a product that exists on nearly every enterprise endpoint. Cross-origin leakage in a business browser can still expose internal app data, tokens, or sensitive page content, so LOW would understate the risk.
What to do — in priority order.
- Force browser relaunch compliance — Make sure auto-updated Chrome actually exits and relaunches so the fixed build is loaded. For a MEDIUM finding there is no mitigation SLA, so use this as a low-friction interim control while completing remediation inside the 365-day window.
- Tighten risky-web-content filtering — Reduce successful lure delivery through web filtering, DNS filtering, ad blocking, and browser isolation for high-risk user groups. There is no mitigation SLA for this severity, so treat it as targeted risk reduction rather than emergency containment.
- Prioritize high-value users first — Patch executives, admins, finance, and developers first because the value of a browser info leak scales with the sensitivity of the sites and sessions they hold. Even without a mitigation SLA, that ordering materially lowers business risk while the broader fleet rolls forward.
- Inventory Chrome by exact version — Query the fleet for Chrome versions below
149.0.7827.53and use that list to drive cleanup, because network exposure scanners will not help much here. For MEDIUM, there is no mitigation SLA — go straight to the 365-day remediation window, but you should still close the visibility gap immediately.
- Perimeter vulnerability scanning does not meaningfully measure exposure here; this is endpoint/browser version risk, not a listening service.
- Relying on auto-update alone does not fully solve it if users never restart Chrome; the vulnerable code stays resident until relaunch.
- Classic WAF rules do not protect users browsing the public internet from a malicious page rendered locally in the browser.
Crowdsourced verification payload.
Run this on the target endpoint or via your software-distribution/EDR scripting channel, not from an auditor workstation. Invoke it with python3 check_chrome_cve_2026_10985.py; no admin rights are required in most cases, though Windows registry reads may work best under the local user or standard endpoint agent context. It checks common Chrome locations on Windows, macOS, and Linux and prints VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env python3
# Check Google Chrome version exposure for CVE-2026-10985
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=ERROR
import os
import platform
import plistlib
import re
import shutil
import subprocess
import sys
MIN_VERSION = (149, 0, 7827, 53)
def parse_version(v):
if not v:
return None
m = re.findall(r"\d+", str(v))
if len(m) < 4:
return None
return tuple(int(x) for x in m[:4])
def cmp_version(a, b):
return (a > b) - (a < b)
def run_cmd(cmd):
try:
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=10)
if p.returncode == 0:
return p.stdout.strip()
except Exception:
pass
return None
def get_windows_version():
# Prefer registry beacon values used by Chrome installers.
try:
import winreg
except Exception:
return None
reg_paths = [
(winreg.HKEY_CURRENT_USER, r"Software\Google\Chrome\BLBeacon", "version"),
(winreg.HKEY_LOCAL_MACHINE, r"Software\Google\Chrome\BLBeacon", "version"),
(winreg.HKEY_LOCAL_MACHINE, r"Software\WOW6432Node\Google\Chrome\BLBeacon", "version"),
(winreg.HKEY_CURRENT_USER, r"Software\Chromium\BLBeacon", "version"),
(winreg.HKEY_LOCAL_MACHINE, r"Software\Chromium\BLBeacon", "version"),
]
for hive, path, name in reg_paths:
try:
with winreg.OpenKey(hive, path) as k:
value, _ = winreg.QueryValueEx(k, name)
if value:
return value
except Exception:
continue
# Fallback to executable version if available.
possible = [
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"),
]
for exe in possible:
if os.path.exists(exe):
try:
import win32api # type: ignore
info = win32api.GetFileVersionInfo(exe, "\\")
ms = info['FileVersionMS']
ls = info['FileVersionLS']
return f"{ms >> 16}.{ms & 0xFFFF}.{ls >> 16}.{ls & 0xFFFF}"
except Exception:
continue
return None
def get_macos_version():
plist_paths = [
"/Applications/Google Chrome.app/Contents/Info.plist",
os.path.expanduser("~/Applications/Google Chrome.app/Contents/Info.plist"),
"/Applications/Chromium.app/Contents/Info.plist",
os.path.expanduser("~/Applications/Chromium.app/Contents/Info.plist"),
]
for p in plist_paths:
if os.path.exists(p):
try:
with open(p, "rb") as f:
data = plistlib.load(f)
for key in ("KSVersion", "CFBundleShortVersionString", "CFBundleVersion"):
if data.get(key):
return str(data[key])
except Exception:
continue
binaries = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"/Applications/Chromium.app/Contents/MacOS/Chromium",
]
for b in binaries:
if os.path.exists(b):
out = run_cmd([b, "--version"])
if out:
return out
return None
def get_linux_version():
candidates = [
"google-chrome",
"google-chrome-stable",
"chromium-browser",
"chromium",
]
for cmd in candidates:
full = shutil.which(cmd)
if full:
out = run_cmd([full, "--version"])
if out:
return out
return None
def main():
system = platform.system().lower()
version_raw = None
if "windows" in system:
version_raw = get_windows_version()
elif "darwin" in system:
version_raw = get_macos_version()
elif "linux" in system:
version_raw = get_linux_version()
else:
print("UNKNOWN: unsupported platform")
sys.exit(2)
parsed = parse_version(version_raw)
if not parsed:
print("UNKNOWN: Chrome version not found")
sys.exit(2)
if cmp_version(parsed, MIN_VERSION) < 0:
print(f"VULNERABLE: detected Chrome/Chromium version {'.'.join(map(str, parsed))} < {'.'.join(map(str, MIN_VERSION))}")
sys.exit(1)
else:
print(f"PATCHED: detected Chrome/Chromium version {'.'.join(map(str, parsed))} >= {'.'.join(map(str, MIN_VERSION))}")
sys.exit(0)
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"UNKNOWN: error during check: {e}")
sys.exit(3)
If you remember one thing.
149.0.7827.53, validate that auto-update plus relaunch enforcement is actually clearing stale builds, and patch your highest-value user groups first; for this MEDIUM finding there is noisgate mitigation SLA — no mitigation SLA — go straight to the 365-day remediation window unless your threat model includes highly targeted browser data theft. Close the vulnerable version population under the noisgate remediation SLA within 365 days, but this does not warrant an emergency weekend change window on the evidence available as of 2026-06-05.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.