This is a weak hinge on an inner door, not a broken front gate
CVE-2026-10981 is an input-validation bug in Chrome's Codecs component. It affects Chrome versions before 149.0.7827.53 on Linux and the 149.0.7827.53/.54 stable train on Windows/macOS; the practical abuse case is a crafted video payload that helps an attacker cross Chrome's sandbox boundary.
paragraph 2: Google's MEDIUM 6.5 label is defensible in a lab, but it overstates the standalone operational risk for enterprise patch queues. The decisive real-world friction is that this is a *chain* bug: the attacker typically needs a separate renderer foothold plus user interaction with attacker-controlled media, and there is no KEV listing, no public exploit, and a very low EPSS signal.
4 steps from start to impact.
Land attacker-controlled media
- Target is running a vulnerable Chrome build before
149.0.7827.53 - Attacker can get the user to load attacker-controlled video content
- User interaction is required
- Enterprise URL filtering, attachment detonation, and browser isolation reduce reach
- This is a client-side bug, so internet-wide exposure scanners do not help attackers find targets
Gain a renderer foothold first
AV:N/PR:N.- A second bug or exploit primitive provides renderer-level code execution or control
- The chain can be synchronized with media decoding
- This prerequisite compounds difficulty sharply
- Modern browser hardening and exploit mitigations can break the first-stage foothold
- No public PoC for this exact CVE lowers opportunistic attacker uptake
Abuse codec validation to cross the sandbox
- The vulnerable codec path is reachable on the target platform
- Attacker-controlled media is decoded in the expected way
- The exploit chain survives Chrome's mitigation stack
- Bug details remain restricted, which usually means reproduction reliability is not commodity yet
- Sandbox-escape chains are brittle across versions, platforms, and mitigations
Operate outside the renderer cage
- Sandbox escape succeeds
- Post-escape payload execution is not blocked by endpoint controls
- EDR, application control, and local privilege boundaries still limit post-escape actions
- The impact is serious *if chained*, but narrow as a standalone issue
The supporting signals.
| Identity check | The user-supplied advisory details line up with Google's 2026-06-02 Chrome 149 stable bulletin entry for CVE-2026-10981 in Codecs; keep it distinct from similarly worded Chrome codec CVEs published the same week. |
|---|---|
| In-the-wild status | No public statement from Google or CISA says this CVE is exploited in the wild as of 2026-06-05. |
| PoC availability | No public PoC or GitHub exploit repo found. The linked Chromium issue 513762354 is still restricted, which usually suppresses copy-paste exploitation. |
| EPSS | 0.00047 (~0.047%) from the supplied intel; that is a very low exploitation-probability signal. |
| KEV status | Not KEV-listed as of 2026-06-05; there is no CISA due date pressure. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N = remote delivery with user interaction, confidentiality impact only, and no direct integrity/availability claim. In practice, the chain requirement makes the raw vector look more reachable than it really is. |
| Affected versions | Chrome before 149.0.7827.53 on Linux; Google and downstream advisories describe the desktop stable train as 149.0.7827.53/.54 for Windows/macOS. |
| Fixed versions | Move to Chrome 149.0.7827.53 or later on Linux and the patched 149.0.7827.53/.54 desktop stable builds on Windows/macOS. For enterprises, the key control is relaunch compliance so the browser actually leaves the vulnerable build. |
| Exposure reality | This is *not* Shodan/Censys/FOFA-style exposure. It is a client-side browser flaw, so external attack-surface platforms won't enumerate it; exposure tracks installed Chrome population, and StatCounter showed Chrome around 70.25% of worldwide desktop browser share in May 2026. |
| Disclosure and reporter | Reported by Google on 2026-05-16 in the Chrome bulletin; CVE record/public disclosure landed on 2026-06-04. |
noisgate verdict.
The single biggest reason this lands in LOW is that it behaves like a *sandbox-escape chain component*, not a clean initial-access bug. Without evidence of active exploitation or a public exploit, the renderer-compromise prerequisite crushes the real-world reachable population.
Why this verdict
- Baseline starts at vendor MEDIUM 6.5 because Chrome is ubiquitous and codec bugs live on a hostile content path
- Renderer-compromise prerequisite drags it down hard: the attacker position is effectively *post-initial-browser-compromise*, which means this is not a front-door exploit for most enterprises
- User interaction narrows reach further: the victim still has to render attacker-controlled media, so email/web filtering and user behavior matter
- No exploitation heat: no KEV, no public PoC, and a supplied EPSS of
0.00047all argue against urgent opportunistic abuse - Broad install base keeps it above IGNORE: Chrome is everywhere, and sandbox escapes remain strategically valuable when paired with another browser bug
Why not higher?
If this were a standalone renderer RCE with reliable remote trigger, the score would jump immediately. But a bug that is mainly valuable *after* another browser compromise is already a narrowed, multi-stage path, and that compounding friction matters more than the theoretical sandbox-escape impact.
Why not lower?
It is still a browser security-boundary issue in one of the most deployed client applications in the enterprise. If an attacker already has a renderer foothold, this kind of bug can turn a contained browser exploit into meaningful endpoint access, so it is not something to dismiss outright.
What to do — in priority order.
- Enforce browser auto-update and relaunch — Make sure managed Chrome channels actually move off vulnerable builds and that users relaunch so the patched binary is loaded. For a LOW noisgate verdict there is no mitigation SLA; treat this as backlog hygiene and verify compliance on the next standard browser-maintenance cycle.
- Prefer browser isolation for high-risk users — Use remote/browser isolation or hardened VDI for executives, admins, and click-prone populations that routinely touch untrusted media. For a LOW verdict there is no mitigation SLA, but this is a sensible standing control rather than a CVE-specific emergency move.
- Block unmanaged and portable browsers — The real risk in large fleets is drift: unmanaged Chrome installs, stale local profiles, and portable copies that miss enterprise update policy. For a LOW verdict there is no mitigation SLA, so fold this into normal endpoint hygiene and software control.
- Watch for browser exploit telemetry — Tune EDR and browser-protection telemetry for Chrome crash spikes, suspicious child processes, and abnormal access to browser data stores. There is no mitigation SLA for LOW, but telemetry gives you early warning if this bug starts appearing in chains.
- A WAF does not help; this is a client-side media parsing issue inside the browser, not a server-side HTTP attack surface.
- Perimeter vulnerability scanning will not find exposure; Shodan-style discovery is irrelevant because the risk is installed browser version, not an open service.
- MFA does not stop exploitation of the browser process itself; it may reduce downstream account abuse, but it does not break the codec-trigger path.
Crowdsourced verification payload.
Run this on the target endpoint or through your software-distribution/EDR script runner. Invoke it with python3 chrome_cve_2026_10981_check.py; it needs only standard user rights and prints VULNERABLE, PATCHED, or UNKNOWN based on the installed Google Chrome version.
#!/usr/bin/env python3
# Check local Google Chrome version against the fixed build for CVE-2026-10981
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import platform
import re
import subprocess
import sys
FIXED = (149, 0, 7827, 53)
def parse_version(text):
m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', text)
if not m:
return None
return tuple(int(x) for x in m.groups())
def run_cmd(cmd):
try:
out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True)
return out.strip()
except Exception:
return None
def get_windows_version():
reg_paths = [
["reg", "query", r"HKLM\SOFTWARE\Google\Chrome\BLBeacon", "/v", "version"],
["reg", "query", r"HKLM\SOFTWARE\WOW6432Node\Google\Chrome\BLBeacon", "/v", "version"],
["reg", "query", r"HKCU\SOFTWARE\Google\Chrome\BLBeacon", "/v", "version"],
]
for cmd in reg_paths:
out = run_cmd(cmd)
if out:
v = parse_version(out)
if v:
return v, out
default_paths = [
r"C:\Program Files\Google\Chrome\Application\chrome.exe",
r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
]
for p in default_paths:
if os.path.exists(p):
ps = [
"powershell",
"-NoProfile",
"-Command",
f"(Get-Item '{p}').VersionInfo.ProductVersion"
]
out = run_cmd(ps)
if out:
v = parse_version(out)
if v:
return v, out
return None, None
def get_macos_version():
candidates = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
os.path.expanduser("~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),
]
for c in candidates:
if os.path.exists(c):
out = run_cmd([c, "--version"])
if out:
v = parse_version(out)
if v:
return v, out
return None, None
def get_linux_version():
candidates = [
["google-chrome", "--version"],
["google-chrome-stable", "--version"],
["/usr/bin/google-chrome", "--version"],
["/usr/bin/google-chrome-stable", "--version"],
]
for cmd in candidates:
out = run_cmd(cmd)
if out:
v = parse_version(out)
if v:
return v, out
return None, None
def main():
system = platform.system()
if system == "Windows":
version, raw = get_windows_version()
elif system == "Darwin":
version, raw = get_macos_version()
elif system == "Linux":
version, raw = get_linux_version()
else:
print(f"UNKNOWN: unsupported platform '{system}'")
sys.exit(2)
if not version:
print("UNKNOWN: Google Chrome version not found")
sys.exit(2)
version_str = ".".join(str(x) for x in version)
fixed_str = ".".join(str(x) for x in FIXED)
if version < FIXED:
print(f"VULNERABLE: installed Chrome {version_str} is older than fixed {fixed_str}")
sys.exit(1)
else:
print(f"PATCHED: installed Chrome {version_str} is at or above fixed {fixed_str}")
sys.exit(0)
if __name__ == "__main__":
main()
If you remember one thing.
149.0.7827.53/.54, and clear them in your normal browser-maintenance workflow; for a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA beyond backlog hygiene, so fold the vendor patch into the next standard browser cycle and document any unmanaged-browser exceptions.Sources
- Google Chrome Stable Channel Update for Desktop (Chrome 149)
- Google Chrome Early Stable Update for Desktop
- Chromium issue 513762354
- Canadian Centre for Cyber Security advisory AV26-544
- CISA Known Exploited Vulnerabilities Catalog
- FIRST EPSS model documentation
- StatCounter desktop browser market share worldwide
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.