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

Inappropriate implementation in WebUI in Google Chrome prior to 149

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

Like a hotel lobby sign pointing to the wrong room while the locks themselves still work

CVE-2026-11225 is a Chrome WebUI domain-spoofing flaw affecting desktop Google Chrome versions before 149.0.7827.53. Google/NVD describe it as an *inappropriate implementation in WebUI* that lets a remote attacker spoof a domain using a crafted domain name. The exact Chromium bug is access-restricted, but from the advisory text and prior public Chrome UI-spoofing bugs, the practical effect is a browser-controlled surface rendering the wrong origin or an ambiguously trusted-looking one.

The vendor baseline of MEDIUM 6.5 is a little rich for real-world enterprise triage. Yes, Chrome is everywhere and browser trust bugs matter, but this chain still requires user interaction, a believable lure, and successful phishing follow-through; there is no code execution, no sandbox escape, no direct data theft primitive, and no infrastructure-side foothold from the bug alone. Chrome itself labeled the underlying Chromium severity Low, and that matches operational reality better than the CVSS math.

"This is a browser trust bug, not a browser takeover bug; useful for phishing, weak for enterprise-wide emergency patching."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Deliver a crafted lookalike URL

The attacker weaponizes a phishing lure around a specially crafted domain name, likely involving long labels, deceptive subdomain structure, or IDN/punycode presentation. Delivery is ordinary email/chat/web-link phishing; no exploit kit or memory corruption is needed.
Conditions required:
  • Attacker can register or control a deceptive domain
  • Target user can be induced to click or navigate
  • Victim is running Chrome before 149.0.7827.53
Where this breaks in practice:
  • Requires a convincing lure and user click
  • Enterprise mail security, URL rewriting, and user training cut a lot of this traffic off before browser render time
  • Many phishing kits fail when the spoofed domain is too obviously weird
Detection/coverage: Email gateways and browser isolation can catch delivery, but vuln scanners do not detect the malicious precondition itself.
STEP 02

Trigger WebUI origin misrendering

On a vulnerable browser, the crafted domain causes a browser UI/WebUI trust surface to render a misleading domain identity. The precise trigger path is not public because Chromium issue 503346647 is restricted, so this step is an inference from NVD wording plus known Chrome UI-spoofing patterns.
Conditions required:
  • Victim opens the crafted URL in vulnerable Chrome
  • The specific domain structure required by the hidden bug is satisfied
Where this breaks in practice:
  • This is not a generic 'any URL spoofs any site' class; it likely depends on edge-case domain formatting
  • Modern Chrome anti-spoof hardening and IDN handling usually constrain how far visual deception can go
  • Browser auto-update reduces window fast in managed fleets
Detection/coverage: Traditional network IDS/WAF coverage is poor. Browser version inventory will find exposure; reproducer-based validation is limited because the bug details are restricted.
STEP 03

Convert confusion into user action

The attacker still has to turn the spoof into something useful: credential harvesting, OAuth consent, download approval, or trust elevation in the user's mind. The vulnerability's impact is therefore bounded by human follow-on behavior rather than automatic browser compromise.
Conditions required:
  • User trusts the spoofed browser-controlled UI element
  • A downstream phishing or social-engineering flow is present
Where this breaks in practice:
  • MFA, passkeys, IdP risk scoring, and conditional access all reduce payoff
  • No direct confidentiality or availability impact occurs unless the user hands something over
  • Blast radius is per-user/session, not enterprise-wide host compromise
Detection/coverage: Detection shifts to phishing telemetry: IdP impossible-travel/risky sign-in, suspicious OAuth grants, proxy logs, and SOC-reported lookalike domains.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence found of active exploitation as of 2026-06-06; not listed in CISA KEV.
Public PoC availabilityNo public PoC located. The referenced Chromium issue 503346647 is restricted, so exact repro details are not public.
EPSS0.0002 from the provided intel block — effectively floor-level exploit probability, consistent with a niche UI-spoof class.
KEV statusAbsent from the CISA KEV catalog; no KEV date and no federal due date.
Vendor vs realityCISA-ADP/NVD shows 6.5 MEDIUM, but the CVE text says Chromium security severity: Low. For enterprise patch queues, the Chromium rating is closer to reality.
CVSS vector meaningAV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N means remote and easy to trigger, but it depends on user interaction and lands as integrity/UI deception, not host compromise.
Affected versionsDesktop Google Chrome prior to 149.0.7827.53 on Windows, macOS, and Linux per NVD CPE data.
Fixed versionsFixed at 149.0.7827.53; Google also shipped 149.0.7827.53/.54 to Windows and macOS in the early stable rollout. Treat 149.0.7827.53 or later as patched.
Exposure/scanning realityThis is a client-side browser flaw, so Shodan/Censys/FOFA-style exposure counts are not meaningful. Reachability is basically 'can your users browse attacker content?' — which means phishing surface, not open ports.
Disclosure / reporterDisclosed 2026-06-04. Reporter attribution was not public in accessible sources because the linked Chromium issue is permission-restricted.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.9/10)

The decisive downgrading factor is that this bug is phishing amplification only: it requires user interaction and a successful social-engineering step before anything of value happens. There is no direct system compromise path, and the blast radius stays bounded to the deceived user rather than turning into fleet-level browser RCE or credential dumping by itself.

HIGH Severity downgrade based on attacker-position and impact friction
MEDIUM Exact trigger mechanics, because Chromium issue details are restricted

Why this verdict

  • User-interaction gate: exploitation starts with a phishing click, which is immediate downward pressure versus unauthenticated server-side bugs
  • No host compromise primitive: the bug spoofs trust signals but does not provide code execution, sandbox escape, file write, or automatic data exfiltration
  • Population is broad but payoff is narrow: Chrome is ubiquitous, yet each attack still has to individually fool a user and then cash out through separate phishing workflow
  • Controls exist at adjacent layers: email security, browser updates, Safe Browsing, MFA/passkeys, and IdP risk controls all reduce real-world success
  • No exploitation signal: no KEV, no public campaign reporting, no public PoC, and a near-floor EPSS score all argue against emergency reprioritization

Why not higher?

A higher rating would need either a direct technical compromise path or strong evidence that the spoof is broadly reliable and already being abused. We have neither. Even if the UI deception is convincing, the attack still depends on a human doing the wrong thing afterward, which sharply limits consistency and blast radius.

Why not lower?

This is still a browser trust failure in one of the most deployed enterprise applications on earth. Even without code execution, domain/origin spoofing can materially improve phishing conversion, especially against high-value users, so calling it IGNORE would understate the risk.

05 · Compensating Control

What to do — in priority order.

  1. Enforce Chrome auto-update — Make sure enterprise policy is actually landing and endpoints are not pinned below 149.0.7827.53. For a LOW verdict there is no SLA, so do this in normal browser hygiene cycles rather than as an incident action.
  2. Prioritize high-risk user cohorts — Push faster browser uptake for admins, finance, execs, and IdP-heavy users because phishing payoff is highest there. Even without a formal mitigation deadline at this severity, these groups are where UI-spoof bugs hurt most.
  3. Tighten anti-phishing controls — Lean on mail filtering, URL detonation, Safe Browsing policy, and IdP conditional access to kill the surrounding phishing chain that this CVE depends on. For a LOW verdict, fold changes into the regular defensive tuning cycle rather than emergency CAB.
  4. Watch for lookalike-domain abuse — Hunt for suspicious IDN/punycode and long-subdomain domains in mail telemetry, proxy logs, and brand-monitoring feeds. This does more practical damage reduction than trying to signature-match an unpublished browser repro.
What doesn't work
  • A WAF does not help; this is not your server being exploited, it is the user's browser rendering trust indicators incorrectly.
  • Perimeter vulnerability scanning will not tell you exploitability here; it can maybe inventory browser versions, but it cannot validate the user-deception conditions.
  • Classic network IDS signatures are weak value because the malicious ingredient is a crafted domain presentation, not a stable exploit payload.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint itself or via your software-distribution/EDR live-response tooling. Invoke with python3 check_chrome_cve_2026_11225.py or point at a specific binary with python3 check_chrome_cve_2026_11225.py --path "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; standard user rights are usually enough, though some Windows installs may require access to registry or program files metadata.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# Check exposure to CVE-2026-11225 (Google Chrome WebUI domain spoofing)
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import argparse
import os
import platform
import re
import subprocess
import sys
from pathlib import Path

THRESHOLD = (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 cmp_version(a, b):
    return (a > b) - (a < b)


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


def get_version_from_binary(path):
    rc, out = run_cmd([path, '--version'])
    if rc is None:
        return None
    return parse_version(out)


def get_windows_version_from_reg():
    try:
        import winreg
    except Exception:
        return None

    keys = [
        (winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon', 'version'),
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Google\Chrome\BLBeacon', 'version'),
        (winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Google\Chrome\BLBeacon', 'version'),
    ]

    for hive, subkey, value_name in keys:
        try:
            with winreg.OpenKey(hive, subkey) as k:
                value, _ = winreg.QueryValueEx(k, value_name)
                ver = parse_version(str(value))
                if ver:
                    return ver
        except OSError:
            continue
    return None


def find_windows_binary():
    candidates = [
        os.path.join(os.environ.get('ProgramFiles', r'C:\Program Files'), 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(os.environ.get('ProgramFiles(x86)', r'C:\Program Files (x86)'), 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(os.environ.get('LocalAppData', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'),
    ]
    for c in candidates:
        if c and os.path.exists(c):
            return c
    return None


def find_macos_binary():
    candidates = [
        '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        str(Path.home() / 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
    ]
    for c in candidates:
        if os.path.exists(c):
            return c
    return None


def find_linux_binary():
    candidates = ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser']
    for c in candidates:
        rc, out = run_cmd([c, '--version'])
        if rc is not None and parse_version(out):
            return c
    paths = [
        '/usr/bin/google-chrome',
        '/usr/bin/google-chrome-stable',
        '/snap/bin/chromium',
        '/usr/bin/chromium',
        '/usr/bin/chromium-browser',
    ]
    for p in paths:
        if os.path.exists(p):
            return p
    return None


def determine_version(explicit_path=None):
    if explicit_path:
        return get_version_from_binary(explicit_path), explicit_path

    system = platform.system().lower()

    if system == 'windows':
        ver = get_windows_version_from_reg()
        if ver:
            return ver, 'registry'
        binary = find_windows_binary()
        if binary:
            return get_version_from_binary(binary), binary
        return None, 'not found'

    if system == 'darwin':
        binary = find_macos_binary()
        if binary:
            return get_version_from_binary(binary), binary
        return None, 'not found'

    binary = find_linux_binary()
    if binary:
        return get_version_from_binary(binary), binary
    return None, 'not found'


def main():
    parser = argparse.ArgumentParser(description='Check if local Chrome is vulnerable to CVE-2026-11225')
    parser.add_argument('--path', help='Path to Chrome binary')
    args = parser.parse_args()

    ver, source = determine_version(args.path)
    if not ver:
        print(f'UNKNOWN - Could not determine Chrome version (source: {source})')
        sys.exit(2)

    ver_str = '.'.join(map(str, ver))
    threshold_str = '.'.join(map(str, THRESHOLD))

    if cmp_version(ver, THRESHOLD) < 0:
        print(f'VULNERABLE - Chrome version {ver_str} is older than fixed version {threshold_str} (source: {source})')
        sys.exit(1)
    else:
        print(f'PATCHED - Chrome version {ver_str} is at or newer than fixed version {threshold_str} (source: {source})')
        sys.exit(0)


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

If you remember one thing.

TL;DR
Monday morning: do not treat this like an emergency zero-day, but do clean it up through your normal managed-browser channel. Inventory endpoints still below 149.0.7827.53, verify Chrome auto-update policy is working, and accelerate updates for high-risk user groups this cycle; for a LOW verdict there is no noisgate mitigation SLA and the noisgate remediation SLA is no SLA (treat as backlog hygiene), so there is no separate emergency blocking action to invent here.

Sources

  1. NVD CVE-2026-11225
  2. Chrome Releases - Early Stable Update for Desktop
  3. Chromium issue 503346647
  4. CISA Known Exploited Vulnerabilities Catalog
  5. FIRST EPSS API documentation
  6. CWE-451: UI Misrepresentation of Critical Information
  7. GovCERT.HK alert for multiple Chrome vulnerabilities
  8. SecurityWeek coverage of Chrome 149 release
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.