This is a booby-trapped revolving door, not an unlocked loading dock
CVE-2026-10906 is a use-after-free in Chrome WebAuthentication affecting Google Chrome before 149.0.7827.53 on Linux and before 149.0.7827.53/54 on Windows and macOS, disclosed on 2026-06-04. In plain English: a malicious site can drive Chrome into reusing freed memory during a WebAuthn flow, creating a path to renderer compromise or crash if the victim is steered through the right interaction sequence.
Google rated it HIGH (7.5), which is defensible in a lab because browser memory corruption is serious. In enterprise reality, that overstates near-term patch urgency: the chain needs web delivery, user interaction, and a sufficiently reliable exploit against modern Chrome mitigations, and the browser sandbox sharply reduces blast radius unless the attacker also has a follow-on escape. With no KEV listing, no public PoC located, and a very low EPSS, this looks more like a patch-on-schedule browser bug than an emergency fleet event.
4 steps from start to impact.
Land the victim on attacker-controlled WebAuthn content
- Unauthenticated remote reach to a user via the web
- Victim uses Chrome below 149.0.7827.53
- Target visits attacker-controlled content
- This is client-side, so there is no direct internet-facing service to mass-scan and hit at will
- Enterprise web filtering, Safe Browsing, mail security, and user behavior all reduce delivery success
Trigger the vulnerable WebAuthentication path
- Page runs in a supported WebAuthn origin context
- User performs the required interaction sequence
- Exploit reliably reaches the vulnerable code path
- The vendor CVSS already says AC:H and UI:R; that matters here
- WebAuthn flows are more interaction-heavy than a simple drive-by page load
- Some enterprises restrict or rarely use passkeys/security keys, reducing reachable population
Convert memory corruption into code execution
- Attacker has exploit engineering capability
- Target build and platform line up with the exploit assumptions
- Chrome mitigations are bypassed well enough for stable execution
- No verified public PoC or exploit kit tie-in found
- Browser exploitation reliability is fragile across builds and platforms
- A crash is much easier than controlled execution
Break out of the renderer sandbox for meaningful host impact
- Initial code execution occurs in a sandboxed renderer or similarly constrained process
- Attacker has a second-stage escape or valuable in-browser objective
- Chrome's sandbox and site isolation are explicit downward pressure on impact
- Single-bug chains in modern Chrome are materially harder to monetize than vendor CVSS suggests
The supporting signals.
| In-the-wild status | No verified active exploitation found in the sources reviewed, and not listed in CISA KEV as of this assessment. |
|---|---|
| Proof-of-concept availability | No public PoC located via public GitHub/Exploit-DB checks. That does *not* mean exploit development is impossible; it means there is no obvious commodity starting point. |
| EPSS | 0.00084 from the user-supplied intel, which is roughly 0.084% modeled 30-day exploitation probability. That is low and supports de-prioritizing against actively exploited browser bugs. |
| KEV status | Not KEV-listed. No CISA date added or due date applies. |
| CVSS vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H — remote and no auth help the score, but high attack complexity plus required user interaction are real operational brakes. |
| Affected versions | Google Chrome prior to 149.0.7827.53 on Linux and prior to 149.0.7827.53/54 on Windows/macOS. |
| Fixed versions | Patch level is 149.0.7827.53 (Linux) and 149.0.7827.53/54 (Windows/macOS). Enterprises on Extended Stable should validate whether their downstream channel has incorporated the fix rather than assuming major-version parity. |
| Exposure / scanning reality | This is not a scan-the-internet service exposure. Shodan/Censys-style internet census data is largely irrelevant here because the reachable surface is the browser endpoint population, not a listening daemon. *Inference from attack model, not from a server census.* |
| Disclosure timeline | Chrome 149 stable shipped on 2026-06-02; the CVE was publicly disclosed in release materials on 2026-06-04. |
| Researcher / reporting credit | Reported by Weipeng Jiang (@Krace) of VRI on 2026-04-17, per Google's release note. |
noisgate verdict.
The decisive factor is compound exploitation friction: this is a client-side browser memory bug that needs web delivery, user interaction, and reliable exploit engineering against modern Chrome hardening. Chrome's sandbox means a one-bug story usually stops short of full host compromise, which keeps this out of the urgent enterprise patch bucket absent exploitation evidence.
Why this verdict
- User-driven chain: the attacker does not get a one-packet hit; they need the victim in a crafted WebAuthn flow, which is meaningfully narrower than generic browse-to-own bugs.
- High-complexity exploit: the vendor vector's
AC:Hmatters. Reliable browser memory-corruption exploitation on modern Chrome is specialist work, especially without a public PoC. - Contained initial blast radius: Chromium explicitly treats compromised renderers as a threat case and uses sandboxing and Site Isolation to limit damage, so the first win is often not the final enterprise-impacting win.
- No active exploitation signal: not in KEV, no verified campaign use, and the supplied EPSS is extremely low.
- Ubiquity prevents a LOW: Chrome is everywhere, delivery is over the web, and if someone does build a stable exploit, reach is broad.
Why not higher?
Because this is not a server-side pre-auth RCE with broad unaided reach. Every extra prerequisite pushes down: the attacker needs user interaction, a WebAuthn-capable interaction path, reliable memory-corruption exploitation, and likely a second bug for system-level outcomes. That is too much friction for HIGH in a 10,000-host prioritization queue absent exploitation evidence.
Why not lower?
Because Chrome is a massive endpoint population and browsers are exposed to hostile content all day. A real memory-safety bug in a ubiquitous browser still deserves disciplined patching even when the current threat telemetry is quiet.
What to do — in priority order.
- Force auto-update compliance — Make sure enterprise policy actually keeps Chrome current and does not strand users on lagging channels. For a MEDIUM verdict there is no mitigation SLA, but this is the cleanest risk reducer before the ≤365-day remediation window closes.
- Harden browser egress paths — Use Secure Web Gateway, DNS filtering, and phishing controls to reduce the chance that users reach attacker-controlled WebAuthn content. This directly attacks the first step of the chain and should be maintained continuously while patch rollout completes.
- Restrict risky browser exceptions — Audit enterprise Chrome policies for disabled sandboxing, relaxed site isolation, unusual extension allowances, or unmanaged developer flags. These exceptions increase exploit reliability and should be removed during normal hardening, well before the remediation deadline.
- Monitor browser crash spikes — Collect Chrome crash and EDR telemetry for sudden increases tied to suspicious domains or user campaigns. It will not prevent exploitation, but it can expose failed exploit attempts and help scope exposure during remediation.
- A network IPS signature is not a dependable control here because the exploit is embedded in normal browser content and pivots on client-side memory state, not a clean protocol pattern.
- Perimeter vuln scanning does not meaningfully solve this; there is no listening Chrome service to census like a VPN or appliance.
- MFA is largely irrelevant to the exploitation step. It may reduce follow-on identity abuse, but it does not stop the WebAuthn memory-corruption trigger.
Crowdsourced verification payload.
Run this on the target endpoint or through your EDR/live-response tool. Invoke it with python3 check_cve_2026_10906.py on Windows, macOS, or Linux; no admin rights are required unless your environment blocks access to browser binaries or app metadata.
#!/usr/bin/env python3
# check_cve_2026_10906.py
# Detect whether the local Google Chrome installation is vulnerable to CVE-2026-10906
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import platform
import plistlib
import re
import subprocess
import sys
from pathlib import Path
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 ver_to_str(v):
return '.'.join(str(x) for x in v) if v else 'unknown'
def is_vulnerable(v):
return v is not None and v < FIXED
def candidates_windows():
paths = []
envs = [os.environ.get('PROGRAMFILES'), os.environ.get('PROGRAMFILES(X86)'), os.environ.get('LOCALAPPDATA')]
suffixes = [
r'Google\Chrome\Application\chrome.exe',
r'Chromium\Application\chrome.exe'
]
for base in envs:
if not base:
continue
for suf in suffixes:
p = Path(base) / Path(suf)
paths.append(p)
return paths
def candidates_macos():
return [
Path('/Applications/Google Chrome.app'),
Path.home() / 'Applications/Google Chrome.app',
Path('/Applications/Chromium.app'),
Path.home() / 'Applications/Chromium.app'
]
def candidates_linux_cmds():
return [
['google-chrome', '--version'],
['google-chrome-stable', '--version'],
['chromium-browser', '--version'],
['chromium', '--version']
]
def get_windows_versions():
found = []
for p in candidates_windows():
if p.exists():
try:
out = subprocess.check_output([str(p), '--version'], stderr=subprocess.STDOUT, text=True, timeout=5)
v = parse_version(out)
found.append((str(p), v))
except Exception:
found.append((str(p), None))
return found
def get_macos_versions():
found = []
for app in candidates_macos():
plist = app / 'Contents' / 'Info.plist'
if plist.exists():
try:
with open(plist, 'rb') as f:
data = plistlib.load(f)
v = parse_version(data.get('CFBundleShortVersionString', '') or data.get('CFBundleVersion', ''))
found.append((str(app), v))
except Exception:
found.append((str(app), None))
return found
def get_linux_versions():
found = []
for cmd in candidates_linux_cmds():
try:
out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True, timeout=5)
v = parse_version(out)
found.append((' '.join(cmd[:-1]), v))
except Exception:
continue
# de-duplicate by path/label
uniq = []
seen = set()
for item in found:
if item[0] not in seen:
uniq.append(item)
seen.add(item[0])
return uniq
def main():
system = platform.system().lower()
if 'windows' in system:
installs = get_windows_versions()
elif 'darwin' in system:
installs = get_macos_versions()
elif 'linux' in system:
installs = get_linux_versions()
else:
print('UNKNOWN')
print('Unsupported platform:', platform.system())
sys.exit(2)
if not installs:
print('UNKNOWN')
print('No Chrome/Chromium installation found')
sys.exit(2)
vuln = []
patched = []
unknown = []
for name, ver in installs:
if ver is None:
unknown.append((name, ver))
elif is_vulnerable(ver):
vuln.append((name, ver))
else:
patched.append((name, ver))
for name, ver in installs:
print(f'{name}: {ver_to_str(ver)}')
print(f'Fixed threshold: {ver_to_str(FIXED)}')
if vuln:
print('VULNERABLE')
sys.exit(1)
if patched and not vuln:
print('PATCHED')
sys.exit(0)
print('UNKNOWN')
sys.exit(2)
if __name__ == '__main__':
main()
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.