← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-10997 · CWE-732 · Disclosed 2026-06-04

Insufficient policy enforcement in Extensions in Google Chrome prior to 149

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

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.

"This is a bad-policy-after-bad-install bug, not a clean remote foothold."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Deliver a malicious extension

The attacker needs the victim to install a Chrome extension they control, whether through phishing, fake productivity tooling, cloned web-store branding, or sideload-friendly enterprise abuse. The bug does not give the attacker code execution by itself; it only becomes reachable once the malicious extension is present.
Conditions required:
  • 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
Where this breaks in practice:
  • 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
Detection/coverage: Network scanners will miss this. Detection is mostly via browser management inventory, EDR telemetry for extension installation, Chrome policy audits, and Chrome Web Store review/extension ID monitoring.
STEP 02

Trigger the policy enforcement gap

Once installed, the malicious extension exercises the vulnerable Extensions policy path to obtain behavior Chrome should have constrained. The public metadata indicates a policy-enforcement weakness rather than memory corruption, so exploitation is likely deterministic once the attacker controls the extension logic.
Conditions required:
  • Malicious extension runs in the victim browser profile
  • The extension reaches the specific restricted operation or boundary guarded by the flawed policy check
Where this breaks in practice:
  • 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
Detection/coverage: Very limited signature coverage unless a scanner keys directly on Chrome version. Runtime abuse may only surface as unusual extension behavior, suspicious extension API use, or browser-integrity anomalies.
STEP 03

Abuse browser integrity

The declared impact is 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.
Conditions required:
  • Victim actively uses the compromised browser profile
  • Extension has access to target sites or workflows the attacker wants to influence
Where this breaks in practice:
  • 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
Detection/coverage: Look for unauthorized extension IDs, newly installed CRX artifacts, policy deviations under Chrome management, and helpdesk reports of altered browser behavior.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed active exploitation found in the sources reviewed; *not* listed in CISA KEV as of the available catalog reference.
Proof-of-concept availabilityNo 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.
EPSSUser-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 statusNot KEV-listed per the user intel block and consistent with the reviewed CISA KEV catalog.
CVSS meaningVendor 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 versionsGoogle 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 versionsPatched 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 realityThis 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 dateUser-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 / reporterNo credited external reporter was identified in the reviewed public sources.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.9/10)

The decisive down-rating factor is that exploitation starts with *installing a malicious extension*, which means the attacker already needs successful social engineering or weak extension governance. This sharply limits the reachable population and makes the bug far less urgent than Chrome's remotely triggerable renderer, sandbox, or memory-corruption issues.

MEDIUM Severity downgrade from vendor MEDIUM to LOW
MEDIUM Assessment of attack preconditions based on public metadata and Chrome enterprise policy behavior
LOW Exact exploit mechanics because the full vendor bug narrative is not public in reviewed sources

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.

05 · Compensating Control

What to do — in priority order.

  1. Lock down extension installs — Use 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.
  2. Block external extensions — Enable 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.
  3. Review high-risk extension populations — Inventory endpoints with unrestricted extension installation, non-store install sources, or excessive extension counts. Those populations are your real exposure set and should be prioritized for policy cleanup during normal backlog hygiene.
  4. Alert on new extension IDs — Feed Chrome extension inventory into EDR/SIEM and flag first-seen IDs, especially those not on your approved list. This will not stop the bug, but it shrinks dwell time when the chain starts with social engineering.
What doesn't work
  • 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.
06 · Verification

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.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/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()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do *not* let the vendor's 6.5 bully this into the same queue as remotely reachable Chrome memory-corruption bugs. For this reassessed LOW, there is no noisgate mitigation SLA and no noisgate remediation SLA — treat it as backlog hygiene: verify your Chrome fleet is rolling forward past 149.0.7827.53, and spend your actual time this cycle finding populations that still allow ungoverned extension installs. If you discover broad unrestricted extension installation in a sensitive user tier, fix that policy weakness in the next normal hardening window and absorb the browser patch in the routine evergreen update stream.

Sources

  1. Google Chrome Releases - Early Stable Update for Desktop
  2. Chrome Enterprise - Extension Settings policy
  3. Chrome Enterprise - BlockExternalExtensions policy
  4. Chrome Enterprise - ExtensionInstallSources policy
  5. Chrome Enterprise - ExtensionInstallForcelist policy
  6. Chrome Enterprise Help - Set Chrome app and extension policies (Windows)
  7. FIRST - EPSS API documentation
  8. CISA - Known Exploited Vulnerabilities Catalog
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.