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

Inappropriate implementation in File Input in Google Chrome prior to 149

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

This is a fake label on a file picker, not a master key to the browser

CVE-2026-11228 is a Chrome File Input security-UI bug affecting versions before 149.0.7827.53. In plain English: a malicious page can apparently make the browser present misleading file-input UI, but only if the attacker first gets the user onto the page and then convinces them to perform the required click flow or other specific UI gestures. The stated impact is UI spoofing / integrity-only misrepresentation, not code execution, sandbox escape, or cross-origin data theft.

The supplied MEDIUM 4.3 score already reflects user interaction, but even that feels a bit generous for enterprise prioritization. Google’s own June 2, 2026 stable-release notes classify CVE-2026-11228 as Low, and that matches reality better: this is a socially-driven, single-user deception issue with no evidence of exploitation, no public weaponized tooling, no internet-scannable service exposure, and very limited blast radius unless you already assume the user can be talked through the attack.

"This is a one-user UI trick, not a fleet-scale break-in: patch it, but don't let a 4.3 score jump your queue."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Deliver a lure page with crafted HTML/JS

The attacker needs a webpage that exercises the vulnerable File Input UI path and persuades the user to interact with it. The practical 'tool' here is just a phishing or lure page using crafted HTML around a file picker; no public exploit kit or offensive framework appears to exist for this CVE.
Conditions required:
  • Unauthenticated remote access to the victim via web/email/chat lure
  • Victim uses Chrome older than 149.0.7827.53
  • User visits attacker-controlled content
Where this breaks in practice:
  • This starts with social engineering, not drive-by compromise
  • Enterprise URL filtering, mail filtering, and user suspicion cut reachability hard
  • No public exploit framework lowers attacker efficiency
Detection/coverage: Secure web gateway, email gateway, and browser history/EDR telemetry may show the lure delivery, but vulnerability scanners generally only confirm version exposure.
STEP 02

Walk the user through the required file-input gesture

The bug description explicitly requires the user to engage in specific UI gestures. That means the attacker must reliably steer the victim through a file-selection flow, which is much less dependable than a one-click browser exploit and often breaks on user hesitation, browser chrome differences, or enterprise hardening.
Conditions required:
  • User interaction with the page
  • User completes the relevant file-input flow
  • Browser UI renders the misleading state in a usable way
Where this breaks in practice:
  • Multi-step UI interaction sharply reduces exploit reliability
  • Users may notice odd file-picker behavior
  • Small UI/layout differences across platforms can make social engineering brittle
Detection/coverage: Hard to detect directly. Browser telemetry may show file-picker invocation; DLP or user reports are more realistic than signature detection.
STEP 03

Exploit the spoofed UI outcome

If the deception works, the attacker gains only the benefit of the spoof: misleading the user about what they are selecting or trusting in that browser moment. The impact is bounded to that user session and does not by itself grant code execution, privilege escalation, or fleet-wide persistence.
Conditions required:
  • Spoofed UI successfully influences user decision-making
  • The surrounding business process gives that decision value
Where this breaks in practice:
  • Impact is integrity-only and session-scoped
  • No direct host compromise or lateral movement from the CVE alone
  • Many workflows still require the user to notice or confirm downstream actions
Detection/coverage: Post-event detection is mostly indirect: help-desk reports, suspicious uploads/downloads, DLP alerts, or forensics tied to the lure site.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public exploitation evidence found as of 2026-06-05; not in CISA KEV.
Proof-of-concept availabilityNo public PoC or exploit framework located in primary-source checking; this looks like a researcher-reported UI bug, not an already-weaponized chain.
EPSS0.00022 (user-supplied intel), which is effectively *floor-level* exploit probability.
KEV statusNot listed in the CISA KEV catalog as checked on 2026-06-05.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N — remote and unauthenticated, but user-driven and integrity-only.
Affected versionsGoogle Chrome prior to 149.0.7827.53; Chrome’s June 2, 2026 desktop stable post covers the fixed train.
Fixed versionsDesktop stable: 149.0.7827.53 (Linux) and 149.0.7827.53/54 (Windows/Mac) per Chrome release notes; Android stable notes say mobile carries the same desktop security fixes in 149.0.7827.59.
Exposure modelThis is a client-side browser flaw, not an internet-listenable service. Shodan/Censys/FOFA are not meaningful exposure measures here; your exposure is your managed browser version inventory.
Disclosure timelineCVE published 2026-06-04; stable-channel fix shipped 2026-06-02.
Reporter / severity mismatchChrome release notes attribute the bug to Umar Farooq and label it Low. That is lower than the supplied MEDIUM 4.3 metadata and better matches the real attack friction.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (2.6/10)

The decisive factor is the required user choreography: this is not just user interaction, it is a specific file-input gesture flow that has to succeed cleanly for the attacker to get any value. Combine that with integrity-only impact and no exploitation evidence, and this lands in backlog territory rather than emergency patching.

HIGH Attack-path friction is materially higher than the supplied 4.3 score implies
MEDIUM Public exploit availability assessment
HIGH Low enterprise blast radius once exploited

Why this verdict

  • Downgrade for multi-step user action: this requires a victim to visit a malicious page *and* complete specific UI gestures, which is much less reliable than a normal browser RCE lure.
  • Downgrade for bounded impact: the described outcome is UI spoofing / integrity-only, not code execution, sandbox escape, credential theft by default, or cross-origin read.
  • Downgrade for exposure reality: Chrome is widely deployed, but this bug is not remotely enumerable or internet-facing; only users who hit attacker content and follow the flow are reachable.
  • Downgrade for weak attacker utility: there is no KEV entry, no public exploitation evidence, and no public PoC found, which matters when deciding what jumps the queue for 10,000 endpoints.
  • Keep it non-zero: it still affects a mass-deployed browser and can support phishing or workflow manipulation, so it is not noise.

Why not higher?

A higher rating would need one of the usual amplifiers: active exploitation, a public exploit chain, trivial one-click abuse, or impact beyond deceptive UI. None of those are present here. The bug’s required human choreography is the kind of compounding friction that should push severity down, not up.

Why not lower?

It is still a security bug in a ubiquitous client application, and browser UI trust boundaries matter. If an attacker can consistently mislead users during file-selection flows, that can still enable real business harm in specific workflows, so this should not be fully ignored.

05 · Compensating Control

What to do — in priority order.

  1. Enforce Chrome auto-update — Make sure enterprise policy keeps Chrome on the current stable train so this class of client-side backlog item self-resolves during normal maintenance. For a LOW finding there is no mitigation SLA and no remediation SLA in noisgate terms, so handle it as routine browser hygiene rather than a special campaign.
  2. Block high-risk lure delivery paths — Use mail filtering, secure web gateway controls, and browser isolation where you already have them to reduce phishing pages that drive users into odd file-upload flows. This is the only meaningful compensating layer because the exploit starts with content delivery; for LOW, do this opportunistically during normal policy tuning rather than as an emergency change.
  3. Keep users off unmanaged browser builds — Inventory and retire stale Chrome channels, portable copies, and unmanaged local installs, because version sprawl is the actual exposure multiplier for browser CVEs like this. For LOW, fold this into your standard endpoint compliance program instead of a one-off exception process.
  4. Watch DLP for anomalous file-selection outcomes — If the business risk is users being tricked into selecting or uploading the wrong file, DLP and upload telemetry are better guardrails than network IDS. Apply to sensitive user groups first, especially finance, HR, and admins, as part of routine control improvement.
What doesn't work
  • Perimeter vulnerability scanning does not meaningfully reduce risk here because this is not a remotely reachable server-side surface.
  • Network IDS signatures are weak compensation; the dangerous part is deceptive browser UI plus user action, not a distinctive packet pattern.
  • MFA is generally irrelevant to the exploit step itself; it may protect downstream account abuse, but it does not stop the file-input spoof flow.
06 · Verification

Crowdsourced verification payload.

Run this on the endpoint itself or from your software-distribution/EDR remote shell. Invoke with python3 check_chrome_cve_2026_11228.py on macOS/Linux or py check_chrome_cve_2026_11228.py on Windows; no admin rights are required for local app version checks, though some registry paths may be more reliable with standard user read access intact.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_chrome_cve_2026_11228.py
# Determine whether Google Chrome installed on this host is vulnerable to CVE-2026-11228.
# Vulnerable: Chrome version < 149.0.7827.53
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import os
import platform
import re
import shutil
import subprocess
import sys
from typing import List, Optional, Tuple

FIXED = (149, 0, 7827, 53)
VERSION_RE = re.compile(r'(\d+)\.(\d+)\.(\d+)\.(\d+)')


def parse_version(text: str) -> Optional[Tuple[int, int, int, int]]:
    m = VERSION_RE.search(text or '')
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def cmp_ver(a: Tuple[int, int, int, int], b: Tuple[int, int, int, int]) -> int:
    return (a > b) - (a < b)


def run_cmd(cmd: List[str]) -> Optional[str]:
    try:
        out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True, timeout=10)
        return out.strip()
    except Exception:
        return None


def check_windows() -> List[Tuple[str, Tuple[int, int, int, int]]]:
    found = []
    paths = [
        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 p in paths:
        if p and os.path.exists(p):
            out = run_cmd(['wmic', 'datafile', 'where', f'name="{p.replace('\\', '\\\\')}"', 'get', 'Version', '/value'])
            ver = parse_version(out or '')
            if ver:
                found.append((p, ver))

    reg_queries = [
        r'HKLM\SOFTWARE\Google\Chrome\BLBeacon',
        r'HKLM\SOFTWARE\WOW6432Node\Google\Chrome\BLBeacon',
        r'HKCU\Software\Google\Chrome\BLBeacon',
    ]
    for key in reg_queries:
        out = run_cmd(['reg', 'query', key, '/v', 'version'])
        ver = parse_version(out or '')
        if ver:
            found.append((key, ver))

    return dedupe(found)


def check_macos() -> List[Tuple[str, Tuple[int, int, int, int]]]:
    found = []
    paths = [
        '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
    ]
    for p in paths:
        if os.path.exists(p):
            out = run_cmd([p, '--version'])
            ver = parse_version(out or '')
            if ver:
                found.append((p, ver))
    return dedupe(found)


def check_linux() -> List[Tuple[str, Tuple[int, int, int, int]]]:
    found = []
    bins = ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser']
    for b in bins:
        exe = shutil.which(b)
        if exe:
            out = run_cmd([exe, '--version'])
            ver = parse_version(out or '')
            if ver:
                found.append((exe, ver))
    return dedupe(found)


def dedupe(items: List[Tuple[str, Tuple[int, int, int, int]]]) -> List[Tuple[str, Tuple[int, int, int, int]]]:
    seen = set()
    result = []
    for path, ver in items:
        key = (path, ver)
        if key not in seen:
            seen.add(key)
            result.append((path, ver))
    return result


def main() -> int:
    system = platform.system().lower()
    if 'windows' in system:
        installs = check_windows()
    elif 'darwin' in system:
        installs = check_macos()
    elif 'linux' in system:
        installs = check_linux()
    else:
        print('UNKNOWN')
        print(f'Unsupported platform: {platform.system()}')
        return 2

    if not installs:
        print('UNKNOWN')
        print('No Chrome/Chromium installation detected or version could not be read.')
        return 2

    vulnerable = []
    patched = []
    for loc, ver in installs:
        if cmp_ver(ver, FIXED) < 0:
            vulnerable.append((loc, ver))
        else:
            patched.append((loc, ver))

    if vulnerable:
        print('VULNERABLE')
        for loc, ver in vulnerable:
            print(f'{loc}: {".".join(map(str, ver))} < {".".join(map(str, FIXED))}')
        return 1

    if patched:
        print('PATCHED')
        for loc, ver in patched:
            print(f'{loc}: {".".join(map(str, ver))} >= {".".join(map(str, FIXED))}')
        return 0

    print('UNKNOWN')
    return 2


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

If you remember one thing.

TL;DR
Monday morning: do not fast-track this ahead of real browser RCEs, sandbox escapes, or KEV-listed items. Verify your managed Chrome fleet is naturally rolling to 149.0.7827.53+ and clean up any unmanaged laggards, but treat this as backlog hygiene; for a LOW verdict there is noisgate mitigation SLA: no SLA (treat as backlog hygiene) and effectively noisgate remediation SLA-driven rush beyond your normal browser-update cadence. If your browser auto-update is healthy, this is an inventory/compliance check this week, not an incident response event.

Sources

  1. Chrome stable desktop release for version 149
  2. Chrome Releases stable updates index
  3. Chromium issue 454484864
  4. NVD record for CVE-2026-11228
  5. CISA Known Exploited Vulnerabilities catalog
  6. FIRST EPSS project
  7. Google Security Blog: Using Chrome's accessibility APIs to find security bugs
  8. Google Security Blog: Evaluating Mitigations & Vulnerabilities in Chrome
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.