This is a forged employee badge that only matters after someone already got through the lobby
CVE-2026-10997 is an *insufficient policy enforcement* flaw in Chrome Extensions affecting Google Chrome versions prior to 149.0.7827.53. The practical read: a malicious extension can get Chrome to honor fewer restrictions than intended, so an attacker who first persuades a user to install that extension can tamper with browser behavior beyond the normal extension boundary. Based on the vendor score and the adjacent Chrome extension bug pattern, the impact is primarily *integrity abuse inside the browser context*, not unauthenticated drive-by code execution.
Google's MEDIUM 6.5 is fair in a lab where every endpoint freely allows user-installed extensions. In real enterprise fleets, it trends lower because the exploit chain starts with *user-assisted extension installation*, and many mature environments already narrow that population with allowlists, force-install policies, blocked external extensions, or store restrictions. That attacker-position requirement is the whole story here: this is post-social-engineering, not internet-reachable exploitation.
3 steps from start to impact.
Deliver a malicious extension
- User can install extensions or attacker can influence extension deployment
- Victim uses Chrome version earlier than
149.0.7827.53 - Attacker can socially engineer or otherwise deliver the extension
- Managed Chrome deployments often restrict extension installs with
ExtensionSettings, allowlists, or force-install only - Users still see extension permissions and installation flows unless policy suppresses them
- Many enterprises block external CRX installs entirely
Trigger the policy enforcement gap
- Malicious extension runs in the victim browser profile
- The extension reaches the specific restricted operation or boundary guarded by the flawed policy check
- The extension still has to reach the vulnerable code path; not every installed extension will naturally exercise it
- Policy-restricted enterprise environments may limit the exact APIs or install sources the attacker prefers
Abuse browser integrity
I:H with no claimed confidentiality or availability impact, so the likely outcome is unauthorized modification of browser state, navigation, or extension-controlled actions. That can still matter in enterprise workflows if browser trust is part of SSO, transaction approval, or internal-app access.- Victim actively uses the compromised browser profile
- Extension has access to target sites or workflows the attacker wants to influence
- Blast radius is usually one user profile at a time, not the entire endpoint fleet
- Browser sandboxing and extension permission scoping still constrain follow-on abuse compared with an RCE
ExtensionSettings and related Chrome Enterprise controls to move users to allowlist/force-install mode where possible. For a LOW verdict there is no formal mitigation SLA, but this is the single best risk reducer to fold into your next browser hardening change window.BlockExternalExtensions so opportunistic sideloading paths are closed. This especially matters on unmanaged or semi-managed Windows/macOS populations where users can be talked into installing off-store CRX packages.- A perimeter firewall does not help because the vulnerable surface is a local browser extension runtime, not an inbound service.
- A WAF does not meaningfully help because the attacker path is extension installation and local browser abuse, not a vulnerable web endpoint you control.
- Generic patch-prioritization by CVSS alone overstates urgency here; it misses the compounding friction of extension-install prerequisites and enterprise policy controls.
The supporting signals.
| In-the-wild status | No confirmed active exploitation found in the sources reviewed; *not* listed in CISA KEV as of the available catalog reference. |
|---|---|
| Proof-of-concept availability | No authoritative public PoC located in reviewed sources. Expect low barrier for a malicious-extension proof once the vulnerable code path is understood, but that is an inference, not confirmed evidence. |
| EPSS | User-supplied EPSS is 0.00008, which is *extremely low* by any practical patch-priority standard; percentile was not independently verified from the FIRST feed during this review. |
| KEV status | Not KEV-listed per the user intel block and consistent with the reviewed CISA KEV catalog. |
| CVSS meaning | Vendor vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N says *network-deliverable with user interaction*, no privileges required, integrity-only impact. That overstates real exposure because the path effectively depends on installing a malicious extension first. |
| Affected versions | Google Chrome prior to 149.0.7827.53; Google's desktop early-stable note shows the fix in 149.0.7827.53/.54 for Windows and Mac. |
| Fixed versions | Patched in Chrome 149.0.7827.53 and later; Windows/Mac early-stable shipped as 149.0.7827.53/.54 per Google. No distro-style backport advisory was identified in reviewed sources. |
| Exposure reality | This is *not* an internet-scannable server bug. Shodan/Censys/GreyNoise-style exposure data is largely inapplicable because the vulnerable surface is a local browser extension runtime on endpoints, not a listening network service. |
| Disclosure date | User-supplied disclosure date: 2026-06-04; Google's related release note for the patched build was published on 2026-05-29 for early stable desktop. |
| Researcher / reporter | No credited external reporter was identified in the reviewed public sources. |
Sources.
- Google Chrome Releases - Early Stable Update for Desktop
- Chrome Enterprise - Extension Settings policy
- Chrome Enterprise - BlockExternalExtensions policy
- Chrome Enterprise - ExtensionInstallSources policy
- Chrome Enterprise - ExtensionInstallForcelist policy
- Chrome Enterprise Help - Set Chrome app and extension policies (Windows)
- FIRST - EPSS API documentation
- CISA - Known Exploited Vulnerabilities Catalog
Why this verdict
- Requires malicious extension install first: attacker position is effectively *post-social-engineering*. That is not the same thing as unauthenticated remote reachability, so I subtract heavily from the vendor baseline.
- Exposure population is narrowed by enterprise policy: modern Chrome fleets often restrict installs with
ExtensionSettings, forcelists, blocklists, or external-extension blocking. That means a meaningful fraction of enterprise endpoints are unreachable to the first exploit step. - Blast radius is usually one browser profile, not one fleet: the public scoring points to integrity abuse in the browser context, not wormable RCE or host takeover. That keeps consequence real but contained.
Why not higher?
Because this is not a clean drive-by browser exploit. The chain depends on user interaction beyond simply visiting a page, and in many managed environments it also depends on missing or weak extension-control policy. No KEV listing, no exploitation evidence, and negligible EPSS all push hard against a MEDIUM-or-higher operational priority.
Why not lower?
Because if your environment allows broad user extension installs, a malicious extension can still turn this into reliable browser integrity abuse at scale. Chrome is ubiquitous, and browser trust often sits in front of SSO, internal apps, and transaction workflows, so ignoring it entirely would be lazy risk management.
Crowdsourced verification payload.
Run this on the *target endpoint* or through your fleet management agent. Invoke it with python3 chrome_cve_2026_10997_check.py on macOS/Linux or py chrome_cve_2026_10997_check.py on Windows; no admin rights are usually needed, though reading the Windows machine-wide registry is more reliable with standard local user access to HKLM intact.
#!/usr/bin/env python3
# CVE-2026-10997 Chrome version check
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN
import os
import platform
import re
import subprocess
import sys
TARGET = (149, 0, 7827, 53)
def parse_version(text):
m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', text or '')
if not m:
return None
return tuple(int(x) for x in m.groups())
def get_windows_version():
try:
import winreg
except Exception:
winreg = None
paths = [
(r'SOFTWARE\\Google\\Chrome\\BLBeacon', 'version', False),
(r'SOFTWARE\\WOW6432Node\\Google\\Chrome\\BLBeacon', 'version', False),
(r'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Google Chrome', 'DisplayVersion', False),
]
if winreg:
for subkey, value_name, current_user in paths:
hive = winreg.HKEY_CURRENT_USER if current_user else winreg.HKEY_LOCAL_MACHINE
try:
key = winreg.OpenKey(hive, subkey)
val, _ = winreg.QueryValueEx(key, value_name)
ver = parse_version(str(val))
if ver:
return ver, f'registry:{subkey}:{value_name}'
except OSError:
pass
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 exe in candidates:
if exe and os.path.exists(exe):
try:
out = subprocess.check_output([exe, '--version'], stderr=subprocess.STDOUT, text=True, timeout=10)
ver = parse_version(out)
if ver:
return ver, exe
except Exception:
pass
return None, ''
def get_macos_version():
candidates = [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
]
for exe in candidates:
if os.path.exists(exe):
try:
out = subprocess.check_output([exe, '--version'], stderr=subprocess.STDOUT, text=True, timeout=10)
ver = parse_version(out)
if ver:
return ver, exe
except Exception:
pass
return None, ''
def get_linux_version():
commands = [
['google-chrome', '--version'],
['google-chrome-stable', '--version'],
['chromium-browser', '--version'],
['chromium', '--version'],
]
for cmd in commands:
try:
out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True, timeout=10)
ver = parse_version(out)
if ver:
return ver, ' '.join(cmd)
except Exception:
pass
candidates = [
'/opt/google/chrome/chrome',
'/usr/bin/google-chrome',
'/usr/bin/google-chrome-stable',
'/snap/bin/chromium',
'/usr/bin/chromium-browser',
'/usr/bin/chromium',
]
for exe in candidates:
if os.path.exists(exe):
try:
out = subprocess.check_output([exe, '--version'], stderr=subprocess.STDOUT, text=True, timeout=10)
ver = parse_version(out)
if ver:
return ver, exe
except Exception:
pass
return None, ''
def main():
system = platform.system().lower()
if 'windows' in system:
ver, source = get_windows_version()
elif 'darwin' in system:
ver, source = get_macos_version()
else:
ver, source = get_linux_version()
if not ver:
print('UNKNOWN - could not determine installed Chrome/Chromium version')
sys.exit(2)
version_str = '.'.join(str(x) for x in ver)
fixed_str = '.'.join(str(x) for x in TARGET)
if ver < TARGET:
print(f'VULNERABLE - detected version {version_str} via {source}; fixed version is {fixed_str} or later')
sys.exit(1)
else:
print(f'PATCHED - detected version {version_str} via {source}; fixed threshold is {fixed_str}')
sys.exit(0)
if __name__ == '__main__':
main()