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

Inappropriate implementation in Passwords in Google Chrome prior to 149

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

This is a forged master key for the browser's apartment doors, not a bomb in the basement

CVE-2026-10937 is an *inappropriate implementation in Passwords* in Google Chrome that affects versions prior to 149.0.7827.53 on Linux and 149.0.7827.53/.54 on Windows and macOS. Google classifies it as a same-origin-policy bypass, which means attacker-controlled web content may be able to act as though it belongs to a different site origin and reach data or privileges that should stay isolated. In browser terms, that is how session theft, cross-site data exposure, or credential-related abuse starts.

Reality is close to Google's own S1/High bucket even though there is no published CVSS score yet. Chromium's own severity guidance explicitly places *full circumvention of the same origin policy* in High severity, but this still is not Critical in enterprise patch triage because it is a client-side bug that requires a user to render malicious content, has no public in-the-wild evidence, and does not by itself imply native code execution or sandbox escape.

"Assessed at HIGH: full SOP bypass in a ubiquitous browser is dangerous, but it still needs a victim to load attacker content."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Deliver a hostile web page

The attacker needs the victim to load attacker-controlled HTML/JavaScript in Chrome, typically through phishing, malvertising, SEO poisoning, or a compromised legitimate site. The practical weaponized tool here is just a custom web payload served from attacker infrastructure; no implant is needed at this stage.
Conditions required:
  • Victim uses Chrome below 149.0.7827.53/.54
  • Victim visits attacker-controlled or attacker-influenced content
  • The relevant Passwords code path is reachable from the page
Where this breaks in practice:
  • Requires user interaction or a drive-by visit path
  • Secure web gateways, URL filtering, and browser isolation can break delivery
  • Not every Chrome session will hit the vulnerable feature path
Detection/coverage: Traditional vuln scanners rarely see this from the network because it is a client-side browser flaw. Detection is mostly version-based via EDR, software inventory, MDM, or enterprise browser management.
STEP 02

Trigger the SOP bypass in Passwords

The page then exercises the vulnerable Passwords implementation to bypass same-origin policy boundaries. The likely weaponized tool remains attacker JavaScript, but the restricted bug means public exploit details are not yet available; the impact model comes from Chromium's vulnerability description and severity taxonomy.
Conditions required:
  • Bug is reachable from untrusted web content
  • Victim browser has not yet updated
  • Exploit logic successfully reproduces the cross-origin boundary failure
Where this breaks in practice:
  • Bug details are still restricted, slowing commodity weaponization
  • Exploit reliability may depend on page state, stored credentials, or victim workflow
  • Site isolation and normal browser process boundaries can reduce easy follow-on abuse even when SOP is bypassed
Detection/coverage: Exploit behavior may look like suspicious browser-origin access or anomalous DOM/network activity, but signature coverage will be weak until details are public. Expect better coverage from browser telemetry than from perimeter tools.
STEP 03

Read cross-origin data or impersonate another site context

If the bypass is complete, attacker script can exfiltrate sensitive cross-origin data, abuse authenticated web sessions, or interfere with password-related flows. Chromium's published severity guidance treats this class as High specifically because it lets one origin act as or read another origin.
Conditions required:
  • Victim is logged into valuable target sites or has meaningful browser state
  • The attacked origin exposes data or actions worth stealing
  • The SOP bypass is sufficiently broad to cross the required boundary
Where this breaks in practice:
  • Impact is bounded to the victim's browser context, not the whole endpoint or domain
  • Short-lived sessions, step-up auth, and anti-CSRF controls can reduce follow-on value
  • Some sites bind critical actions to re-authentication or user verification
Detection/coverage: UEBA, CASB, IdP anomaly detection, and SaaS audit logs may catch impossible travel, odd session reuse, or suspicious account actions after token/session theft. Endpoint scanners still mainly detect by version, not exploit artifact.
STEP 04

Monetize the stolen browser trust

The attacker uses the captured data, sessions, or site impersonation capability for account takeover, data theft, or business-email-adjacent fraud. The weaponized tool at this stage is whatever follows session compromise: cookie replay, scripted SaaS access, or targeted account abuse.
Conditions required:
  • Stolen data is still valid
  • Target services do not strongly bind sessions to device or re-auth
  • Attacker can act before tokens expire or are revoked
Where this breaks in practice:
  • MFA does not help after session theft, but session binding and conditional access can
  • High-value actions often trigger extra controls
  • Blast radius is per-user and per-session unless the victim is highly privileged
Detection/coverage: Look for new session creation, cookie replay indicators, SaaS admin log anomalies, and browser-originated exfiltration patterns. There is no reliable internet scan signature for this phase.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence of active exploitation found as of 2026-06-04, and it is not in the CISA KEV catalog. That lowers urgency versus Chrome zero-days, but it does not make a full SOP bypass benign.
PoC availabilityNo public PoC, Metasploit module, or widely-circulated exploit write-up was found in open sources during this assessment. The upstream bug remains restricted at Chromium issue 502651056, which slows copycat weaponization.
EPSSEPSS from the supplied intel is 0.00016 (0.016%). That is extremely low modeled 30-day exploitation probability; percentile was not available in the provided source set. Reference format: FIRST EPSS API.
KEV status and datesNot KEV-listed. Disclosure date is 2026-06-04; no CISA KEV add date or federal due date exists because there is no catalog entry. Canonical KEV references: catalog, machine-readable mirror.
Vendor severity / scoring stateGoogle labels the bug High in the Chrome 149 stable release notes, but there is no vendor or authority CVSS score/vector published yet. This assessment therefore starts from Chromium's qualitative severity guidance, not a numeric vendor baseline.
CVSS-style interpretationNo official vector exists. Practically, this behaves like a remote, no-privilege, user-interaction-required, scope-changing browser confidentiality/integrity bug rather than a wormable service flaw. That profile lands in High, not Critical, for enterprise patch priority.
Affected versionsGoogle states the issue affects Chrome versions prior to 149.0.7827.53 on Linux and 149.0.7827.53/.54 on Windows/macOS in the stable release advisory. The early stable post shows the same train entering rollout on 2026-05-29.
Fixed versionsFixed in 149.0.7827.53 for Linux and 149.0.7827.53/.54 for Windows/macOS per the stable release advisory. No authoritative distro backport advisory for this specific CVE was found during this review.
Exposure / scanning realityThis is not meaningfully measurable via Shodan/Censys/FOFA because Chrome is client software, not an internet-exposed service. Your exposure is the size of your browser fleet on Windows, macOS, and Linux, which Google explicitly lists in the release notes.
Disclosure / reporterPublished 2026-06-04; the stable release notes credit Google as the reporter and show the bug was reported on 2026-04-14.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.4/10)

The decisive factor is that this is a same-origin-policy bypass in a massively deployed browser, which can turn a normal web visit into cross-origin data access or session abuse. What keeps it out of Critical is equally important: it is a client-side, user-driven attack path with no public exploitation evidence and no indication of code execution outside the browser security model.

HIGH Affected version range and fixed version identification
MEDIUM Impact estimation from the sparse public description
MEDIUM Severity placement in High rather than Medium

Why this verdict

  • Remote web-deliverable bug: the attacker only needs to get a victim onto hostile content in Chrome; there is no prior host compromise, local foothold, or authentication prerequisite.
  • Full SOP bypass is a real amplifier: Chromium's own severity guidance places full same-origin-policy circumvention in the High bucket because it enables cross-origin reads or impersonation.
  • User interaction is the main downward pressure: this requires a browser session and malicious content delivery, which implies phishing, malvertising, or site compromise rather than direct internet-scale exploitation against a listening service.
  • Client-side only narrows reachable population per attempt: even though Chrome is ubiquitous, an attacker must win one user/browser session at a time; this is not a wormable edge appliance or server-side unauth RCE.
  • No KEV, no public PoC, very low EPSS: lack of exploitation evidence and an EPSS of 0.00016 materially reduce short-term weaponization risk versus Chrome bugs that already have public chains or KEV status.
  • Blast radius is user-context, not system-context: likely outcomes are cross-origin data theft, token/session abuse, or credential-related abuse inside the victim's browser context, not native code execution with endpoint-wide control.

Why not higher?

There is no public evidence that this bug yields native code execution, sandbox escape, or full host compromise. The chain also requires a victim browsing event, and current public data does not show active exploitation, KEV inclusion, or commodity exploit availability.

Why not lower?

A full same-origin-policy bypass in Chrome is not a niche paper cut; it strikes directly at the browser's core trust boundary. In a 10,000-host fleet, that means one successful lure can expose authenticated SaaS sessions and sensitive web data at scale, so backlog treatment would be too relaxed.

05 · Compensating Control

What to do — in priority order.

  1. Enforce minimum Chrome version — Use MDM, EDR software inventory, or enterprise browser management to block or aggressively flag Chrome versions below 149.0.7827.53 on Linux and 149.0.7827.53/.54 on Windows/macOS. For a HIGH verdict, deploy this control within 30 days to satisfy the temporary-risk side of the response while patch rollout catches up.
  2. Turn on forced browser auto-update — Ensure managed Chrome channels cannot linger on vulnerable builds because of user deferral or disabled update services. This is the cleanest fleet-wide compensating control for a browser bug; for HIGH, enforce within 30 days.
  3. Apply remote browser isolation to high-risk cohorts — Put privileged admins, finance, help desk, and other high-phish groups behind RBI/VDI or equivalent isolation for untrusted browsing if you cannot patch them immediately. This reduces the chance that hostile web content reaches the vulnerable renderer path; deploy within 30 days for the exposed cohorts that matter most.
  4. Tighten URL filtering and ad/malware blocking — Since the entry point is attacker-controlled web content, increase blocking for newly registered domains, malicious ad networks, file-sharing lures, and uncategorized sites. This does not fix the bug, but it raises delivery friction and should be tuned within 30 days.
  5. Hunt for stale privileged browser sessions — Reduce follow-on value by shortening session lifetimes where possible and reviewing SaaS admin portals for long-lived sessions from high-value users. This is especially useful if patch rollout will be staggered; complete the policy review within 30 days.
What doesn't work
  • A WAF does not protect a client-side browser vulnerability; the attack runs in the victim's browser after page load.
  • Network perimeter scanning will not find or validate exposure because Chrome is not a server-side listening service here.
  • MFA alone does not stop session theft or cross-origin data abuse once the victim already has an authenticated browser session.
  • Password rotation by itself is not the right primary response; the issue is browser trust-boundary failure, not necessarily stolen stored passwords at rest.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or through your software-distribution/EDR agent with local user rights; admin is helpful on Windows for registry fallback but not strictly required. Invoke it as python3 check_chrome_cve_2026_10937.py or python check_chrome_cve_2026_10937.py --path "C:\Program Files\Google\Chrome\Application\chrome.exe"; it prints VULNERABLE, PATCHED, or UNKNOWN and exits 1, 0, or 2 respectively.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_chrome_cve_2026_10937.py
# Determine whether installed Google Chrome is vulnerable to CVE-2026-10937
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import argparse
import os
import platform
import re
import subprocess
import sys
from shutil import which

WIN_MIN = (149, 0, 7827, 53)  # .53 or later on Windows/macOS is accepted here; Google also shipped .54
MAC_MIN = (149, 0, 7827, 53)
LINUX_MIN = (149, 0, 7827, 53)

VERSION_RE = re.compile(r'(\d+)\.(\d+)\.(\d+)\.(\d+)')


def parse_version(text):
    if not text:
        return None
    m = VERSION_RE.search(text)
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def version_to_str(v):
    return '.'.join(str(x) for x in v) if v else 'unknown'


def run_cmd(cmd):
    try:
        p = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
        out = (p.stdout or '') + ' ' + (p.stderr or '')
        return out.strip()
    except Exception:
        return ''


def compare_versions(found, minimum):
    if found is None:
        return None
    return found >= minimum


def detect_windows(path_hint=None):
    candidates = []
    if path_hint:
        candidates.append(path_hint)
    local = os.environ.get('LOCALAPPDATA', '')
    prog = os.environ.get('ProgramFiles', '')
    progx86 = os.environ.get('ProgramFiles(x86)', '')
    candidates.extend([
        os.path.join(local, 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(prog, 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(progx86, 'Google', 'Chrome', 'Application', 'chrome.exe'),
    ])

    for path in candidates:
        if path and os.path.exists(path):
            out = run_cmd([path, '--version'])
            ver = parse_version(out)
            if ver:
                return path, ver

    reg_queries = [
        [
            'reg', 'query',
            r'HKCU\Software\Google\Chrome\BLBeacon',
            '/v', 'version'
        ],
        [
            'reg', 'query',
            r'HKLM\Software\Google\Chrome\BLBeacon',
            '/v', 'version'
        ],
        [
            'reg', 'query',
            r'HKLM\Software\WOW6432Node\Google\Chrome\BLBeacon',
            '/v', 'version'
        ]
    ]
    for cmd in reg_queries:
        out = run_cmd(cmd)
        ver = parse_version(out)
        if ver:
            return 'registry', ver

    return None, None


def detect_macos(path_hint=None):
    candidates = []
    if path_hint:
        candidates.append(path_hint)
    candidates.extend([
        '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
    ])
    for path in candidates:
        if path and os.path.exists(path):
            out = run_cmd([path, '--version'])
            ver = parse_version(out)
            if ver:
                return path, ver

    plist = '/Applications/Google Chrome.app/Contents/Info.plist'
    if os.path.exists(plist):
        out = run_cmd(['/usr/bin/defaults', 'read', plist, 'KSVersion'])
        ver = parse_version(out)
        if ver:
            return plist, ver

    return None, None


def detect_linux(path_hint=None):
    candidates = []
    if path_hint:
        candidates.append(path_hint)
    for name in ['google-chrome', 'google-chrome-stable', 'chrome', 'chromium', 'chromium-browser']:
        p = which(name)
        if p:
            candidates.append(p)
    candidates.extend([
        '/opt/google/chrome/chrome',
        '/usr/bin/google-chrome',
        '/usr/bin/google-chrome-stable',
    ])
    seen = set()
    for path in candidates:
        if not path or path in seen:
            continue
        seen.add(path)
        if os.path.exists(path):
            out = run_cmd([path, '--version'])
            ver = parse_version(out)
            if ver:
                return path, ver
    return None, None


def main():
    parser = argparse.ArgumentParser(description='Check Google Chrome for CVE-2026-10937 exposure by version.')
    parser.add_argument('--path', help='Explicit path to browser binary', default=None)
    args = parser.parse_args()

    system = platform.system().lower()

    if system == 'windows':
        source, ver = detect_windows(args.path)
        minimum = WIN_MIN
    elif system == 'darwin':
        source, ver = detect_macos(args.path)
        minimum = MAC_MIN
    elif system == 'linux':
        source, ver = detect_linux(args.path)
        minimum = LINUX_MIN
    else:
        print('UNKNOWN: unsupported platform {}'.format(platform.system()))
        sys.exit(2)

    if ver is None:
        print('UNKNOWN: could not determine installed Chrome version')
        sys.exit(2)

    patched = compare_versions(ver, minimum)
    if patched is None:
        print('UNKNOWN: version comparison failed')
        sys.exit(2)

    if patched:
        print('PATCHED: detected version {} from {} (minimum safe {})'.format(version_to_str(ver), source, version_to_str(minimum)))
        sys.exit(0)
    else:
        print('VULNERABLE: detected version {} from {} (requires >= {})'.format(version_to_str(ver), source, version_to_str(minimum)))
        sys.exit(1)


if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, treat this as a fleet browser hygiene problem with real credential/session risk, not as an edge-appliance fire drill. Inventory every managed Chrome instance, fast-track any build below 149.0.7827.53 on Linux or 149.0.7827.53/.54 on Windows/macOS, and use enterprise controls to prevent laggards from lingering; for a HIGH verdict that means the noisgate mitigation SLA is within 30 days, and the noisgate remediation SLA is within 180 days. If you have privileged user groups that browse untrusted content, move them to enforced auto-update and browser isolation first rather than waiting for the long tail.

Sources

  1. Chrome Stable Channel Update for Desktop (Chrome 149)
  2. Chrome Early Stable Update for Desktop
  3. Chromium issue 502651056
  4. Chromium Security FAQ
  5. Chromium Severity Guidelines for Security Issues
  6. CISA Known Exploited Vulnerabilities Catalog
  7. CISA KEV data mirror
  8. FIRST EPSS API documentation
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.