This is finding a loose panel inside the vault after the robber is already locked in the lobby
CVE-2026-11235 is an insufficient policy enforcement flaw in Chrome Compositing affecting Google Chrome versions prior to 149.0.7827.53. The key clause is the whole story: the attacker must have already compromised the renderer process first, and only then can a crafted HTML page be used to gain arbitrary code execution inside a sandbox. That makes this a post-compromise browser-chain primitive, not a one-bug remote workstation takeover.
The published 8.8 HIGH CVSS overstates enterprise urgency if you are scheduling patches across a real fleet. Chrome's own CVE text labels the underlying Chromium security severity as Low, and that lines up better with reality: this bug assumes a prior exploit stage, preserves sandbox confinement, has no known KEV entry, and has extremely low EPSS. It matters to exploit developers building multi-bug chains; it is not the thing that gets an attacker into your environment by itself.
3 steps from start to impact.
Compromise the renderer first
- Victim uses a vulnerable Chrome build earlier than
149.0.7827.53 - Attacker has a separate working renderer-compromise exploit
- Victim reaches attacker-controlled web content
- This CVE is unusable without a prior browser exploit stage
- Modern browser hardening, exploit mitigations, and EDR raise the cost of landing reliable renderer compromise first
- No public one-click PoC for this CVE was found
Trigger the Compositing policy flaw
- Renderer execution already achieved
- Attacker can deliver crafted HTML to the same browser session
- The bug appears to stay within sandbox boundaries rather than breaking out to the OS
- Reliable exploitation likely depends on browser state and exploit choreography, not just simple page delivery
Try to turn sandboxed code execution into real impact
- Successful execution inside the sandbox
- A second post-exploitation path to host-level or identity-level impact
- Sandbox confinement is the biggest downward pressure on risk
- Many enterprises can absorb isolated browser-process compromise better than host compromise
- Additional stages increase failure points and detection opportunities
The supporting signals.
| In-the-wild status | No public evidence of active exploitation found, and not listed in CISA KEV at the time of assessment. |
|---|---|
| Proof-of-concept availability | No public GitHub PoC or turnkey exploit repo located for CVE-2026-11235; exploitation appears to require a custom chain. |
| EPSS | 0.00078 from the prompt intel — extremely low expected near-term exploitation probability. |
| KEV status | Not KEV-listed. CISA's KEV catalog does not show this CVE. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H assumes a clean remote path, but the CVE text itself says the attacker must have already compromised the renderer process. That prerequisite is major real-world friction. |
| Affected versions | Google Chrome prior to 149.0.7827.53. |
| Fixed versions | Desktop stable update shipped as 149.0.7827.53 for Linux and 149.0.7827.53/54 for Windows and Mac. Android release notes state they carry the same desktop security fixes unless otherwise noted. |
| Exposure / scanning reality | This is a client-side browser flaw, not an internet-listening service. Shodan/Censys-style exposure counts are not meaningful; your exposure is your managed Chrome install base. |
| Disclosure date | 2026-06-04. |
| Reporter / source | Public record names Chrome/Google as the source. The linked Chromium issue is restricted, so public researcher attribution is not currently visible. |
noisgate verdict.
The decisive factor is the attacker-position requirement: this bug only matters after a renderer compromise already exists. That makes it a narrow, post-initial-access exploit-chain primitive rather than a stand-alone enterprise intrusion driver, and the remaining sandbox confinement further cuts practical blast radius.
Why this verdict
- Requires prior compromise: the CVE text explicitly requires the attacker to have already compromised the renderer process, which implies a separate exploit stage and is strong downward pressure from the
8.8baseline. - Still sandboxed: successful exploitation yields arbitrary code execution *inside a sandbox*, not a clean host escape. That sharply limits stand-alone business impact.
- No exploitation signal: no KEV listing, no public exploitation evidence found, and the supplied EPSS
0.00078is tiny. - Exposure is broad but not reachable in the same way as a server bug: Chrome is everywhere, but this is not an unauthenticated internet-facing service that attackers can mass-scan and smash directly.
- Detection opportunity compounds across stages: a real attack needs renderer compromise first and likely a follow-on sandbox escape or credential theft second, creating more breakpoints for browser protections and EDR.
Why not higher?
A HIGH or CRITICAL verdict would fit a browser bug that gives unauthenticated remote code execution on first contact or breaks out of the sandbox directly. This one does neither. Its own description bakes in a prior exploit requirement and leaves the attacker sandboxed, which is exactly the kind of friction that should crush a vacuum-severity score.
Why not lower?
It is still a real security boundary failure in a massively deployed client, and it could be useful in a chained campaign. If an attacker already has a renderer foothold, this CVE may help stabilize or extend that position. That keeps it above IGNORE and worth normal patch hygiene.
What to do — in priority order.
- Enforce Chrome auto-update — Pin managed endpoints to current stable and verify update compliance through enterprise browser policy. For a LOW verdict there is no SLA; treat as backlog hygiene, but this is still the cleanest control because version drift is the only broad exposure condition.
- Harden browser process isolation — Keep Chrome sandboxing, site isolation, and exploit-protection features enabled everywhere; do not relax them for compatibility unless there is an exception record. This reduces the value of post-renderer-compromise bugs like this one and should be maintained continuously.
- Prioritize unmanaged browsing populations — Focus first on high-risk user groups that browse unknown content, use developer features, or run without strong EDR/browser management. For LOW, fold this into normal remediation planning rather than emergency action.
- Watch for chained browser detections — Tune EDR and browser telemetry for exploit chains, suspicious renderer crashes, and abnormal Chrome child-process activity. This matters because the real risk comes from combinations, not this CVE in isolation.
- A WAF does not materially help; this is client-side browser logic, not your web app's input path.
- Perimeter internet exposure scanning does not answer the question; Chrome is an endpoint application, so Shodan-style visibility is irrelevant.
- Relying on email filtering alone is weak here because any web delivery path can host the crafted HTML once another renderer exploit exists.
Crowdsourced verification payload.
Run this on the target endpoint or via your software-distribution/EDR remote execution channel. Invoke it as python3 check_cve_2026_11235.py on Linux/macOS or py check_cve_2026_11235.py on Windows; no administrative privileges are required if the Chrome binary is in a standard location.
#!/usr/bin/env python3
# check_cve_2026_11235.py
# Detects whether local Google Chrome version is vulnerable to CVE-2026-11235.
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
import os
import platform
import re
import shutil
import subprocess
import sys
from typing import Optional, Tuple, List
THRESHOLD = (149, 0, 7827, 53)
def parse_version(text: str) -> Optional[Tuple[int, int, int, int]]:
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_and_get_version(cmd: List[str]) -> Optional[Tuple[int, int, int, int]]:
try:
p = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
except Exception:
return None
out = (p.stdout or '') + '\n' + (p.stderr or '')
return parse_version(out)
def candidate_commands() -> List[List[str]]:
system = platform.system().lower()
cmds: List[List[str]] = []
if system == 'windows':
env = os.environ
candidates = [
os.path.join(env.get('ProgramFiles', 'C:\\Program Files'), 'Google', 'Chrome', 'Application', 'chrome.exe'),
os.path.join(env.get('ProgramFiles(x86)', 'C:\\Program Files (x86)'), 'Google', 'Chrome', 'Application', 'chrome.exe'),
os.path.join(env.get('LocalAppData', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'),
]
for path in candidates:
if path and os.path.exists(path):
cmds.append([path, '--version'])
for exe in ['chrome', 'chrome.exe']:
found = shutil.which(exe)
if found:
cmds.append([found, '--version'])
elif system == 'darwin':
candidates = [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
]
for path in candidates:
if os.path.exists(path):
cmds.append([path, '--version'])
found = shutil.which('google-chrome')
if found:
cmds.append([found, '--version'])
else:
for exe in ['google-chrome', 'google-chrome-stable', 'chrome', 'chromium', 'chromium-browser']:
found = shutil.which(exe)
if found:
cmds.append([found, '--version'])
for path in [
'/opt/google/chrome/chrome',
'/usr/bin/google-chrome',
'/usr/bin/google-chrome-stable',
]:
if os.path.exists(path):
cmds.append([path, '--version'])
# Deduplicate while preserving order
unique = []
seen = set()
for cmd in cmds:
key = tuple(cmd)
if key not in seen:
seen.add(key)
unique.append(cmd)
return unique
def main() -> int:
versions = []
for cmd in candidate_commands():
ver = run_and_get_version(cmd)
if ver:
versions.append((cmd[0], ver))
if not versions:
print('UNKNOWN - Google Chrome not found or version unreadable')
return 2
# Prefer the highest discovered version if multiple copies exist
path, ver = sorted(versions, key=lambda x: x[1], reverse=True)[0]
ver_str = '.'.join(str(x) for x in ver)
threshold_str = '.'.join(str(x) for x in THRESHOLD)
if ver < THRESHOLD:
print(f'VULNERABLE - {path} version {ver_str} is older than fixed version {threshold_str}')
return 1
else:
print(f'PATCHED - {path} version {ver_str} is at or newer than fixed version {threshold_str}')
return 0
if __name__ == '__main__':
sys.exit(main())
If you remember one thing.
149.0.7827.53 into your normal browser-update wave, confirm auto-update enforcement, and let EDR/browser telemetry watch for chained exploit behavior; for a LOW verdict there is no mitigation SLA and noisgate remediation SLA is effectively backlog hygiene rather than a hard deadline. If you have unmanaged or high-risk browsing populations, clean those up first, but this CVE by itself does not justify emergency disruption.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.