This is a locked interior fire door, not the front gate
CVE-2026-11113 is an input-validation flaw in Chrome's ANGLE graphics layer, fixed in Chrome 149.0.7827.53 for Linux and 149.0.7827.53/.54 for Windows and macOS. The authoritative description matters: it is not a clean unauthenticated drive-by RCE by itself. It requires a remote attacker to have already compromised the renderer process, then use a crafted HTML page to *potentially* turn that foothold into a sandbox escape.
Google's own Chrome release notes classify it as Medium, while downstream enrichment inflated it to 9.6/Critical by scoring the escape impact in isolation. For enterprise patch prioritization, the renderer-compromise prerequisite is the whole story: this is a second-stage exploit-chain component, not an initial-access bug. Widespread product deployment keeps it relevant, but the lack of KEV, lack of public in-the-wild evidence, and very low supplied EPSS push this well below true emergency browser patching.
3 steps from start to impact.
Compromise the renderer first
- Attacker can get the user to render attacker-controlled web content or extension content
- A separate bug or technique already compromises the renderer process
- This is the biggest brake on severity: the attacker is already past initial access inside the browser
- Modern browser hardening and exploit mitigations make reliable renderer compromise non-trivial
- This CVE cannot be operationalized alone
Hit the ANGLE validation gap
- Renderer already under attacker influence
- ANGLE/WebGL-reachable code path available on the target
- Target build is below the fixed Chrome version
- WebGL/ANGLE reachability can vary by platform, policy, and graphics configuration
- The public commit exposes the area of repair, but not a turnkey weaponized exploit
Attempt sandbox escape
- Exploit chain survives browser mitigations
- The ANGLE flaw can be shaped into a practical escape primitive on the target platform
- Browser sandboxes exist specifically to make this step fail
- Potential escape is not the same as reliable host code execution across enterprise fleets
- Per-host blast radius is limited unless chained into persistence or lateral movement
The supporting signals.
| In-the-wild status | No public exploitation evidence located in the sources reviewed, and not listed in CISA KEV. |
|---|---|
| Proof-of-concept availability | I found no public end-to-end exploit PoC in primary sources. What *is* public is the ANGLE fix commit tied to chromium:500560764, which lowers reverse-engineering cost. |
| EPSS | Supplied intel says 0.00047, which is extremely low and fits a post-compromise chain component rather than a mass-exploitation favorite. |
| KEV status | Not KEV-listed as checked against the CISA Known Exploited Vulnerabilities Catalog. |
| Vendor vs. enriched severity | Chrome release notes call it Chromium security severity: Medium; downstream enrichment assigns 9.6 Critical with CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H. |
| Why CVSS overstates this | The CVSS vector models a high-impact remote browser bug, but the description adds an omitted prerequisite: the attacker must have already compromised the renderer process. |
| Affected versions | Desktop Chrome before 149.0.7827.53; Google's stable update lists 149.0.7827.53 for Linux and 149.0.7827.53/.54 for Windows/macOS. |
| Fixed versions | Patch level is Chrome 149.0.7827.53+ on Linux and 149.0.7827.53/.54+ on Windows/macOS. Enterprises consuming vendor-packaged Chrome builds should verify package backports and staged rollout status. |
| Exposure/scanning reality | There is no useful Shodan/Censys-style internet census here; this is client-side browser exposure. The practical exposed population is your managed Chrome estate, especially users allowed to hit untrusted web content with hardware acceleration/WebGL available. |
| Disclosure and reporting | Published 2026-06-04. Chrome release notes say it was reported by Google on 2026-04-08. The public ANGLE fix commit landed 2026-04-23. |
noisgate verdict.
The decisive factor is the attacker position requirement: this CVE starts after the attacker already owns the renderer process. That makes it a valuable exploit-chain enhancer, but a poor standalone candidate for broad enterprise emergency patching absent active exploitation.
Why this verdict
- Major downgrade for prerequisite: the attacker must have already compromised the renderer process, which means this is post-initial-access inside the browser, not a front-door internet bug.
- No active exploitation signal: no KEV listing, no public campaign evidence found, and the supplied EPSS
0.00047is tiny. - Client-side blast radius: even if exploited, the impact is generally one browser session/host at a time unless paired with follow-on persistence or lateral movement.
Why not higher?
If this were a true no-prereq remote sandbox escape from web content, the Critical label would be defensible. But the published description explicitly narrows it to attackers who have already compromised the renderer, which is a compounding friction point that sharply reduces reachable population and immediate enterprise risk.
Why not lower?
It is still a sandbox escape class issue in an extremely common browser component, and sandbox escapes are exactly the bugs advanced operators chain with renderer exploits. The public fix commit also gives exploit developers useful breadcrumbs, so this is not backlog trivia.
What to do — in priority order.
- Verify browser auto-update health — Make sure managed Chrome channels are actually converging on
149.0.7827.53+across all rings. For a MEDIUM verdict there is no mitigation SLA, so the priority is operational assurance that normal browser update machinery is working rather than emergency exception handling. - Reduce high-risk WebGL exposure where justified — For kiosk, admin, or other high-value populations that routinely touch untrusted content, consider policy-based reduction of WebGL/hardware-acceleration exposure if business impact is acceptable. This is a targeted risk reducer for the ANGLE attack surface, not a fleet-wide default.
- Tighten extension governance — The most important compensating control is upstream of this CVE: reduce the odds of the renderer compromise that must come first. Enforce allowlisting, remove unneeded extensions, and review developer-mode exceptions during the normal remediation window.
- Hunt for browser crash clusters — Look for repeated Chrome renderer/GPU-process crashes, abnormal browser child-process trees, and exploit-protection alerts on users exposed to hostile sites. This helps catch chained exploitation attempts while you move through the remediation window.
- A WAF does not meaningfully help; this is a client-side browser bug reached through rendered content, not a server request filtering problem.
- Internet perimeter vulnerability scanning does not help; there is no externally enumerable service banner for Chrome desktops.
- MFA is irrelevant to exploitation of this flaw itself; it may limit follow-on account abuse, but it does not break the renderer-to-sandbox-escape chain.
Crowdsourced verification payload.
Run this on the target endpoint or through your EDR/remote execution tooling. Invoke it with python3 check_cve_2026_11113.py on macOS/Linux or py check_cve_2026_11113.py on Windows; no admin rights are normally required because it only reads version info from standard install locations and the registry.
#!/usr/bin/env python3
# check_cve_2026_11113.py
# Detect whether local Google Chrome installation is below the fixed version for CVE-2026-11113.
# 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):
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 run_version(cmd):
try:
p = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
out = (p.stdout or '') + ' ' + (p.stderr or '')
return parse_version(out)
except Exception:
return None
def windows_versions():
versions = []
reg_queries = [
["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_queries:
v = run_version(cmd)
if v:
versions.append(("registry", v))
paths = [
os.path.expandvars(r"%ProgramFiles%\Google\Chrome\Application\chrome.exe"),
os.path.expandvars(r"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"),
os.path.expandvars(r"%LocalAppData%\Google\Chrome\Application\chrome.exe"),
]
for path in paths:
if path and os.path.exists(path):
v = run_version([path, "--version"])
if v:
versions.append((path, v))
return versions
def mac_versions():
versions = []
paths = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
os.path.expanduser("~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),
]
for path in paths:
if os.path.exists(path):
v = run_version([path, "--version"])
if v:
versions.append((path, v))
plist_paths = [
"/Applications/Google Chrome.app/Contents/Info.plist",
os.path.expanduser("~/Applications/Google Chrome.app/Contents/Info.plist"),
]
for plist in plist_paths:
if os.path.exists(plist):
v = run_version(["defaults", "read", plist, "CFBundleShortVersionString"])
if v:
versions.append((plist, v))
return versions
def linux_versions():
versions = []
cmds = [
["google-chrome", "--version"],
["google-chrome-stable", "--version"],
["/opt/google/chrome/chrome", "--version"],
]
for cmd in cmds:
v = run_version(cmd)
if v:
versions.append((' '.join(cmd), v))
return versions
def main():
system = platform.system().lower()
found = []
if system == "windows":
found = windows_versions()
elif system == "darwin":
found = mac_versions()
elif system == "linux":
found = linux_versions()
else:
print("UNKNOWN - unsupported platform: {}".format(platform.system()))
sys.exit(2)
if not found:
print("UNKNOWN - Google Chrome not found or version unreadable")
sys.exit(2)
# Deduplicate versions
uniq = {}
for source, ver in found:
uniq[(source, ver)] = True
found = list(uniq.keys())
vulnerable = []
patched = []
for source, ver in found:
if ver < FIXED:
vulnerable.append((source, ver))
else:
patched.append((source, ver))
if vulnerable:
details = '; '.join(["{}={}".format(src, version_str(ver)) for src, ver in vulnerable])
print("VULNERABLE - fixed version is {} ; found {}".format(version_str(FIXED), details))
sys.exit(1)
details = '; '.join(["{}={}".format(src, version_str(ver)) for src, ver in patched])
print("PATCHED - fixed version is {} ; found {}".format(version_str(FIXED), details))
sys.exit(0)
if __name__ == "__main__":
main()
If you remember one thing.
149.0.7827.53+, spot-check high-risk user groups, and fold this into normal browser hygiene. Because the reassessed verdict is MEDIUM, there is no noisgate mitigation SLA — go straight to the 365-day remediation window; the formal noisgate remediation SLA is ≤365 days, though operationally most enterprises should let standard browser updating clear it far sooner.Sources
- Chrome Releases - Stable Channel Update for Desktop (Chrome 149)
- Vulnerability-Lookup entry for CVE-2026-11113
- ANGLE fix commit tied to chromium issue 500560764
- CISA Known Exploited Vulnerabilities Catalog
- FIRST EPSS API documentation
- FIRST EPSS data and stats
- GovCERT.HK alert referencing Chrome 149 vulnerabilities
- SecurityWeek coverage of Chrome 149 release
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.