This is a hidden trapdoor inside a fake maintenance badge, not a burglar kicking in the front door
CVE-2026-11201 is a use-after-free in Chrome ServiceWorker affecting Google Chrome versions before 149.0.7827.53. The published description matters: the attacker must convince a user to install a malicious Chrome extension, and that crafted extension then triggers the memory-corruption bug to reach arbitrary code execution in the browser context. Official Chrome release notes list it as Chromium security severity: Medium, even though downstream CVSS scoring shows 8.8 High.
The vendor-style CVSS is too generous for enterprise prioritization because it treats this like generic network-reachable browser RCE. In reality, the exploit chain begins with a malicious extension install prerequisite, which is a major friction point in managed fleets: extension allowlists, admin install policies, user awareness, Safe Browsing, and store vetting all narrow the reachable population before the bug is even in play.
4 steps from start to impact.
Deliver a trojanized extension
- Attacker can distribute or socially engineer installation of a malicious Chrome extension
- Target users are allowed to install extensions or receive one through unmanaged channels
- Enterprise extension allowlists and force-install policies block most unsanctioned add-ons
- Chrome Web Store vetting and Safe Browsing reduce casual delivery success
- User must take an install action
Land on a vulnerable Chrome build
- Chrome version earlier than 149.0.7827.53 is present
- Auto-update is delayed, broken, or intentionally deferred
- Chrome updates fast in healthy fleets
- Managed browsers are often pinned only briefly for compatibility testing
Trigger the ServiceWorker use-after-free
- Malicious extension can reach the affected ServiceWorker path
- Exploit is stable enough for the target platform/build
- Memory-corruption exploitation is harder than policy-bypass bugs
- Cross-version exploit reliability may be poor without tailored engineering
Achieve browser-context code execution
- Exploit succeeds on the target build
- Victim keeps the malicious extension installed long enough to trigger the chain
- Extension governance can remove the add-on before exploitation
- EDR and browser hardening can still disrupt follow-on behavior
- A network perimeter scanner will not help much; this is not an internet-facing service vulnerability.
- A WAF or edge IPS does not meaningfully reduce risk because the exploit chain is delivered through a browser extension, not a server-side HTTP endpoint.
- MFA is mostly irrelevant to the core flaw; it may protect accounts, but it does not stop a malicious extension from landing or triggering the bug.
The supporting signals.
| In-the-wild status | No public evidence of active exploitation in reviewed sources, and not listed in CISA KEV as of review time (CISA KEV). |
|---|---|
| Proof-of-concept availability | No public PoC found. SynScan currently shows "No technical information available" and the Chromium issue remains restricted (SynScan, Chromium issue). |
| EPSS | 0.009% (1st percentile) per the GitHub advisory, which is extremely low predicted exploitation probability for the next 30 days (GHSA-9pgr-9977-jg98). |
| KEV status | Not KEV-listed; no CISA due date applies (CISA KEV). |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H produces 8.8 High, but that model underweights the practical prerequisite of installing a malicious extension first (GHSA). |
| Affected versions | Google Chrome before 149.0.7827.53. CIRCL mirrors the CNA record showing < 149.0.7827.53 as affected (CIRCL). |
| Fixed versions | 149.0.7827.53 for Linux and 149.0.7827.53/.54 for Windows/macOS in the stable desktop rollout (Chrome Releases). |
| Exposure / scanning data | Not internet-scan-observable in any useful way. This is a client-side browser + malicious-extension chain, so Shodan/Censys/FOFA-style edge counts are the wrong lens; external scanning will not tell you your true exposure. *Inference based on product type and attack path.* |
| Disclosure date | 2026-06-04 in the CNA/CVE record; Chrome stable release notes were published 2026-06-02 (CIRCL, Chrome Releases). |
| Reporter | Reported by Weipeng Jiang (@Krace) of VRI on 2026-04-22 according to Chrome release notes (Chrome Releases). |
Sources.
Why this verdict
- Major prerequisite discount: attacker needs the victim to install a malicious extension first; that is not the same thing as unauthenticated drive-by web exploitation.
- Exposure discount: only endpoints running Chrome < 149.0.7827.53 *and* lacking strong extension governance are realistically reachable.
- Threat-intel discount: no KEV, no public PoC, and 0.009% EPSS / 1st percentile all push this below a typical browser-RCE emergency.
Why not higher?
A higher rating would make sense for a pure drive-by browser bug with active exploitation or a reliable public exploit. This one is bottlenecked by the need to land a malicious extension first, which means many enterprises can eliminate most of the reachable population with policy alone.
Why not lower?
It is still a memory-corruption code-execution bug in Chrome, and Chrome is everywhere. If your fleet allows broad extension installs, or you have a history of users adopting unsanctioned add-ons, the reachable population grows quickly and the residual risk stays meaningful.
Crowdsourced verification payload.
Run this on the target endpoint or via your software-distribution/EDR scripting channel. Invoke it with python3 check_chrome_cve_2026_11201.py on macOS/Linux or py check_chrome_cve_2026_11201.py on Windows; no admin rights are required for version-only checks, though broader path visibility helps.
#!/usr/bin/env python3
# check_chrome_cve_2026_11201.py
# Detects whether local Google Chrome version is vulnerable to CVE-2026-11201.
# 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:
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=10)
out = (p.stdout or '') + '\n' + (p.stderr or '')
return out.strip()
except Exception:
return ''
def get_version_windows():
candidates = [
["reg", "query", r"HKCU\Software\Google\Chrome\BLBeacon", "/v", "version"],
["reg", "query", r"HKLM\Software\Google\Chrome\BLBeacon", "/v", "version"],
["reg", "query", r"HKLM\Software\WOW6432Node\Google\Chrome\BLBeacon", "/v", "version"],
]
for cmd in candidates:
out = run_cmd(cmd)
v = parse_version(out)
if v:
return v, 'registry'
exe_candidates = [
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 exe_candidates:
if path and os.path.exists(path):
out = run_cmd([path, "--version"])
v = parse_version(out)
if v:
return v, path
return None, ''
def get_version_macos():
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):
out = run_cmd([path, "--version"])
v = parse_version(out)
if v:
return v, path
return None, ''
def get_version_linux():
cmds = [
["google-chrome", "--version"],
["google-chrome-stable", "--version"],
["chromium-browser", "--version"],
["chromium", "--version"],
]
for cmd in cmds:
out = run_cmd(cmd)
v = parse_version(out)
if v:
return v, ' '.join(cmd)
return None, ''
def main():
system = platform.system().lower()
if 'windows' in system:
version, source = get_version_windows()
elif 'darwin' in system:
version, source = get_version_macos()
else:
version, source = get_version_linux()
if not version:
print('UNKNOWN - Could not determine Google Chrome version on this host')
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 - Detected Chrome {version_str} from {source}; fixed version is {fixed_str} or later')
sys.exit(1)
else:
print(f'PATCHED - Detected Chrome {version_str} from {source}; fixed version threshold is {fixed_str}')
sys.exit(0)
if __name__ == '__main__':
main()