This is a burglar getting into the building lobby, not the server room
CVE-2026-10964 is an integer overflow in Chrome's V8 JavaScript engine affecting Google Chrome versions prior to 149.0.7827.53 on Linux and 149.0.7827.53/54 on Windows and macOS. A victim must be lured to attacker-controlled web content, after which the attacker can achieve arbitrary code execution inside the browser sandbox via crafted HTML/JavaScript.
paragraph 2: Google's HIGH label is understandable if you score the memory corruption in isolation, but it overstates enterprise impact. The decisive real-world friction is that successful exploitation lands in a sandboxed renderer, not on the host, so meaningful workstation compromise usually still needs a second bug or a separate post-exploit path; combine that with required user interaction, no KEV entry, and a very low EPSS, and this grades down to a solid MEDIUM for patch-priority purposes.
4 steps from start to impact.
Deliver malicious web content
- Victim runs Chrome older than
149.0.7827.53 - Victim visits attacker-controlled or attacker-influenced content
- JavaScript execution is permitted
- Requires user interaction (
UI:R) - Email filtering, DNS filtering, Safe Browsing, and ad-blocking reduce delivery success
- Enterprise browser isolation or remote rendering can break the chain before exploit delivery
Trigger V8 integer overflow
- Exploit must match the vulnerable V8 build closely
- Victim browser protections must not block the triggering script
- No public PoC or exploit repo surfaced in the sources reviewed
- Modern mitigations in Chrome make reliable exploitation harder than the
AC:Llabel suggests operationally - Exploit reliability usually drops across OS, patch, and hardware variations
Gain code execution in the sandboxed renderer
- Successful memory corruption exploit in the renderer
- Chrome sandbox remains the security boundary
- The sandbox sharply limits blast radius
- Host-level persistence or broad lateral-movement actions are blocked without another weakness or user-assisted escape path
- Enterprise EDR often catches unusual child process, file, or token behavior if the actor tries to leave the sandbox
Attempt post-sandbox impact
- Attacker has a second exploit, misconfiguration, or alternate abuse path
- Target environment lacks layered browser containment
- No active exploitation evidence in KEV or vendor advisory
- No public second-stage chain tied to this CVE was found
- Most enterprises can tolerate the residual risk briefly while normal browser updating catches up
149.0.7827.53/54+. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but in practice browsers should be closed out in the next normal endpoint update cycle, not left to drift.- Perimeter vulnerability scanning doesn't help much here because Chrome is a client application, not a listening network service.
- Relying on MFA doesn't meaningfully reduce exploitability; this chain starts with web content execution, not account takeover.
- Traditional WAF controls are irrelevant unless you happen to control the delivery site; the vulnerable surface is the browser engine on the endpoint.
The supporting signals.
| In-the-wild status | No authoritative evidence of active exploitation was found in the reviewed sources. Not listed in CISA KEV, and Google's release post does not flag exploitation. |
|---|---|
| Public exploit / PoC | No public PoC, Metasploit module, or Exploit-DB entry surfaced for CVE-2026-10964 in the reviewed sources. Treat exploit availability as not publicly confirmed. |
| EPSS | User-supplied EPSS is 0.0008, which is very low and aligns with the current absence of exploitation reporting. Percentile was not authoritatively confirmed from accessible FIRST output during this assessment. |
| KEV status | No KEV listing found on the CISA catalog page reviewed for this assessment; therefore no CISA due date applies. |
| CVSS vector meaning | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H translates to remote reachability with no prior auth, but the exploit still needs user interaction and the published description says code execution is inside the sandbox. |
| Affected versions | Chrome prior to 149.0.7827.53. Vendor release notes specify 149.0.7827.53 for Linux and 149.0.7827.53/54 for Windows and macOS. |
| Fixed versions | Upgrade to Chrome 149.0.7827.53 or later on Linux, and 149.0.7827.54 or later on Windows/macOS where that build is offered. For Chromium-derived browsers, consume the equivalent vendor backport/update once available. |
| Exposure reality | This is a client-side browser bug, not an internet-facing service. Shodan/Censys-style internet exposure counts are not meaningful; exposure maps to your installed browser fleet and how often users browse untrusted content. |
| Disclosure / patch date | Chrome stable release published 2026-06-02; NVD published the CVE on 2026-06-04 and NVD shows last modification on 2026-06-05. |
| Reporter | Google's release notes attribute this issue to Google, reported on 2026-05-08, not an external researcher. |
Sources.
Why this verdict
- Down from vendor 8.8: the published impact is renderer code execution *inside the sandbox*, not direct workstation compromise.
- User interaction required: the attacker needs the victim to load malicious content, which makes delivery materially less reliable in managed enterprise fleets.
- No exploitation heat: no KEV entry, no reviewed source indicating in-the-wild abuse, and a very low user-supplied EPSS all push this below emergency patch status.
- Wide product deployment is the main upward pressure: Chrome is everywhere, so even a sandboxed bug still deserves cleanup through standard browser update governance.
Why not higher?
If this were a demonstrated sandbox escape, a full browser-to-OS chain, or KEV-listed with live exploitation, it would jump fast. But the current public description stops at sandboxed execution, and that boundary matters more than the raw memory-corruption label.
Why not lower?
This is still remotely triggerable through everyday browsing with no authentication barrier, and Chrome's installed base is massive. Browser memory corruption bugs also have a history of being chained, so dismissing it as LOW would understate the residual risk.
Crowdsourced verification payload.
Run this on the target endpoint or through your software-distribution/EDR scripting channel. Invoke with python3 check_chrome_cve_2026_10964.py; no admin rights are usually needed, though Windows registry access to machine-wide installs works best in a normal user session with local read access.
#!/usr/bin/env python3
# check_chrome_cve_2026_10964.py
# Determine whether local Google Chrome is vulnerable to CVE-2026-10964
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import platform
import subprocess
import sys
import re
TARGET = (149, 0, 7827, 53)
def parse_version(s):
m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', s or '')
if not m:
return None
return tuple(int(x) for x in m.groups())
def cmp_version(a, b):
return (a > b) - (a < b)
def get_version_from_command(cmd):
try:
out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True, timeout=10)
return parse_version(out.strip())
except Exception:
return None
def check_linux():
candidates = [
['google-chrome', '--product-version'],
['google-chrome-stable', '--product-version'],
['chromium', '--product-version'],
['chromium-browser', '--product-version'],
]
for cmd in candidates:
v = get_version_from_command(cmd)
if v:
return v, 'command:' + ' '.join(cmd)
return None, None
def check_macos():
plist = '/Applications/Google Chrome.app/Contents/Info.plist'
if os.path.exists(plist):
v = get_version_from_command(['/usr/bin/defaults', 'read', plist.replace('/Contents/Info.plist', ''), 'KSVersion'])
if not v:
v = get_version_from_command(['/usr/bin/defaults', 'read', plist, 'CFBundleShortVersionString'])
if v:
return v, plist
alt = os.path.expanduser('~/Applications/Google Chrome.app/Contents/Info.plist')
if os.path.exists(alt):
v = get_version_from_command(['/usr/bin/defaults', 'read', alt.replace('/Contents/Info.plist', ''), 'KSVersion'])
if not v:
v = get_version_from_command(['/usr/bin/defaults', 'read', alt, 'CFBundleShortVersionString'])
if v:
return v, alt
return None, None
def check_windows():
try:
import winreg
except Exception:
return None, 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'),
]
for hive, path, name in reg_paths:
try:
with winreg.OpenKey(hive, path) as key:
value, _ = winreg.QueryValueEx(key, name)
v = parse_version(str(value))
if v:
return v, 'registry:' + path
except Exception:
pass
file_candidates = [
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'),
os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'),
]
for exe in file_candidates:
if os.path.exists(exe):
v = get_version_from_command(['powershell', '-NoProfile', '-Command', f"(Get-Item '{exe}').VersionInfo.ProductVersion"])
if v:
return v, exe
return None, None
def main():
system = platform.system().lower()
version = None
source = None
if 'linux' in system:
version, source = check_linux()
elif 'darwin' in system:
version, source = check_macos()
elif 'windows' in system:
version, source = check_windows()
else:
print('UNKNOWN: unsupported platform')
sys.exit(2)
if not version:
print('UNKNOWN: could not determine Chrome version')
sys.exit(2)
if cmp_version(version, TARGET) < 0:
print(f'VULNERABLE: detected Chrome version {".".join(map(str, version))} from {source}; fixed version is {".".join(map(str, TARGET))} or later')
sys.exit(1)
else:
print(f'PATCHED: detected Chrome version {".".join(map(str, version))} from {source}; meets or exceeds {".".join(map(str, TARGET))}')
sys.exit(0)
if __name__ == '__main__':
main()