This is a bad lock on a car door, not a magic key to every machine
CVE-2025-6554 is a V8 type confusion bug in Chrome that affects desktop releases before 138.0.7204.96 on Windows, before 138.0.7204.92/.93 on macOS, and before 138.0.7204.92 on Linux. A malicious site can feed crafted HTML/JavaScript into the browser and turn that memory-safety mistake into an arbitrary read/write primitive inside the browser process.
Google's HIGH 8.1 baseline is basically fair. The big downward pressures are real: the attacker still needs user interaction, a reachable vulnerable browser, and in many full-compromise scenarios a second bug or a browser sandbox escape. But those frictions are offset by the two facts that matter most to an enterprise fleet manager: Chrome is everywhere and Google plus CISA both confirm real-world exploitation.
4 steps from start to impact.
Land the victim on attacker-controlled web content
- Target uses Chrome/Chromium-based browser in the affected range
- Target visits attacker-controlled or attacker-influenced content
- JavaScript execution is allowed
- Requires UI:R; no click, no bug
- Email gateways, Safe Browsing, DNS filtering, and browser isolation cut a lot of commodity delivery
- Internal-only or kiosk workflows with restricted browsing reduce reachable population
Trigger the V8 type confusion and win a renderer primitive
- Correct vulnerable build and platform
- Exploit reliably shaped for that Chrome/V8 release
- Browser-side mitigations not sufficient to break the exploit chain
- Browser exploitation is version-fragile; heap shaping and reliability are not one-size-fits-all
- Google pushed a configuration mitigation on June 26, 2025 before the stable update
- Patch levels move quickly in managed Chrome fleets
Abuse browser-process access for theft or staging
- Victim is authenticated to useful SaaS/apps
- Sensitive content is reachable from the compromised browsing session
- Outbound exfiltration is not blocked
- Chrome sandboxing and site isolation limit what a single renderer bug gets you
- HttpOnly cookies, CSP, CASB controls, and browser isolation narrow easy data theft paths
- Without a second bug, impact may stay inside the browser/session boundary
Chain to full device compromise only if a second bug is available
- Operator has or acquires a compatible second-stage exploit
- Target defenses fail to stop the post-renderer stage
- No public, authoritative exploit chain showing guaranteed one-bug full host compromise was available at review time
- EDR, exploit protection, and OS hardening are much more likely to catch the native stage than the initial renderer bug
- A perimeter vuln scan will not save you here; this is client software, not an exposed server banner problem
- EDR alone is not enough; a renderer-only exploit can stay quiet until a second stage appears
- A WAF does nothing for users browsing out to malicious internet content
- Email filtering alone is incomplete because the same exploit can arrive via compromised websites, ads, chat links, or search poisoning
The supporting signals.
| In-the-wild status | Confirmed exploited. Google states it is aware of an exploit in the wild, and CISA added it to KEV on 2025-07-02. |
|---|---|
| KEV | Listed in CISA KEV as *Google Chromium V8 Type Confusion Vulnerability*; KEV due date was 2025-07-23 for FCEB agencies. |
| Proof-of-concept availability | Public GitHub material exists, but what's readily visible is mixed quality. The clearly visible repo from Muhammednihalmp is training-oriented and non-weaponized; other repo names are surfaced by aggregators, but reliability and completeness are unclear. |
| EPSS | User-supplied EPSS is 0.0158. That's low in isolation, but for a KEV-listed browser zero-day EPSS is not the deciding signal. |
| CVSS vector meaning | AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N means remote, no auth, low complexity, but user interaction is required and the published impact does not claim direct availability loss. |
| Affected versions | Chrome before 138.0.7204.96 per CNA/NVD, with Google shipping fixes as 138.0.7204.96/.97 for Windows, 138.0.7204.92/.93 for macOS, and 138.0.7204.92 for Linux. |
| Fixed versions and backports | Google patched on 2025-06-30. Debian tracked the Chromium fix as 138.0.7204.92-1~deb12u1 for bookworm backports. |
| Exposure / scanning reality | This is client software, so internet scanners like Shodan/Censys/FOFA are mostly useless for direct exposure measurement. Your exposure is the size of your Chrome fleet and how quickly you can force browser restart plus update adoption. |
| Disclosure and reporting | Published 2025-06-30; reported by Clément Lecigne of Google's Threat Analysis Group on 2025-06-25; Google says a config mitigation was pushed on 2025-06-26. |
Sources.
- Google Chrome Releases - Stable Channel Update for Desktop (June 30, 2025)
- NVD - CVE-2025-6554
- CISA - Adds One Known Exploited Vulnerability to Catalog (July 2, 2025)
- OpenCVE record for CVE-2025-6554
- Debian Security Tracker - CVE-2025-6554
- Debian Security Advisory DSA-5955-1
- FIRST EPSS - Data and Statistics
- GitHub training repo referencing CVE-2025-6554
Why this verdict
- Active exploitation keeps the floor high: Google says an exploit exists in the wild and CISA KEV confirms this is not theoretical
- User interaction subtracts real risk: attacker position is *unauthenticated remote*, but it still implies a delivery problem that modern email, web, DNS, and browser controls can disrupt
- Single-bug impact is narrower than 'full RCE everywhere': arbitrary read/write in the browser process is serious, but many enterprise-worst outcomes still require a second vulnerability or a compatible post-browser path
Why not higher?
I am not calling this CRITICAL because the chain is not one-packet, wormable, or broadly automatable. The need for a victim browsing event and the likelihood that full host compromise needs another bug are meaningful friction points in real deployments.
Why not lower?
I am not dropping this to MEDIUM because this is Chrome, not a niche product, and Google explicitly says it is already being exploited. Once a browser zero-day is live, exposure is measured in users, not servers, and your reachable population is usually enormous.
Crowdsourced verification payload.
Run this on the target endpoint or through your EDR/remote execution tooling. Invoke it with python3 check_cve_2025_6554.py on Windows, macOS, or Linux; standard user rights are usually enough because it only reads local version information from common install paths and the Windows registry.
#!/usr/bin/env python3
# check_cve_2025_6554.py
# Detect likely exposure to CVE-2025-6554 on local Chrome installs.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import platform
import re
import shutil
import subprocess
import sys
def parse_ver(s):
m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', s)
return tuple(int(x) for x in m.groups()) if m else None
def cmp_ver(a, b):
return (a > b) - (a < b)
def run_cmd(cmd):
try:
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=10)
out = (p.stdout or '') + (p.stderr or '')
return out.strip()
except Exception:
return ''
def get_windows_version():
# Prefer registry App Paths / BLBeacon if present
reg_paths = [
["reg", "query", r"HKLM\Software\Google\Chrome\BLBeacon", "/v", "version"],
["reg", "query", r"HKCU\Software\Google\Chrome\BLBeacon", "/v", "version"],
["reg", "query", r"HKLM\Software\WOW6432Node\Google\Chrome\BLBeacon", "/v", "version"],
]
for cmd in reg_paths:
out = run_cmd(cmd)
v = parse_ver(out)
if v:
return v, out
common = [
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 common:
if os.path.exists(path):
out = run_cmd([path, "--version"])
v = parse_ver(out)
if v:
return v, out
return None, ''
def get_macos_version():
apps = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
os.path.expanduser("~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),
"/Applications/Chromium.app/Contents/MacOS/Chromium",
]
for path in apps:
if os.path.exists(path):
out = run_cmd([path, "--version"])
v = parse_ver(out)
if v:
return v, out
return None, ''
def get_linux_version():
bins = ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "chrome"]
for b in bins:
p = shutil.which(b)
if p:
out = run_cmd([p, "--version"])
v = parse_ver(out)
if v:
return v, out
return None, ''
def main():
system = platform.system()
version = None
raw = ''
fixed = None
if system == 'Windows':
version, raw = get_windows_version()
fixed = (138, 0, 7204, 96)
elif system == 'Darwin':
version, raw = get_macos_version()
fixed = (138, 0, 7204, 92)
elif system == 'Linux':
version, raw = get_linux_version()
fixed = (138, 0, 7204, 92)
else:
print('UNKNOWN - unsupported platform:', system)
sys.exit(2)
if not version:
print('UNKNOWN - Chrome/Chromium version not found')
sys.exit(2)
print(f'Detected version: {version[0]}.{version[1]}.{version[2]}.{version[3]}')
print(f'Raw version output: {raw}')
print(f'Fixed threshold for {system}: {fixed[0]}.{fixed[1]}.{fixed[2]}.{fixed[3]}+')
if cmp_ver(version, fixed) < 0:
print('VULNERABLE')
sys.exit(1)
else:
print('PATCHED')
sys.exit(0)
if __name__ == '__main__':
main()