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

Inappropriate implementation in Chrome for iOS in Google Chrome on iOS prior to 149

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

This is a fake badge on the front desk, not a skeleton key to the building

CVE-2026-11285 is a UI spoofing flaw in Chrome for iOS that affects versions prior to 149.0.7827.53. A remote attacker can serve a crafted HTML page that makes browser UI or security context look more trustworthy than it really is, which can improve phishing or social-engineering success against the person viewing the page.

The published 4.3/MEDIUM score is already modest, but in enterprise reality this lands lower. It is client-side, iOS-only, requires user interaction, and the technical impact ceiling is just low-integrity deception, not code execution, sandbox escape, data theft, or tenant-wide compromise; Chrome's own bug bucket also labels it Low.

"A phishing polish bug, not a fleet-burner: patch it, but don't let it jump the line"
02 · The Attack Path

3 steps from start to impact.

STEP 01

Deliver the lure page

The attacker hosts a crafted HTML page and gets a target to open it in Chrome for iOS using a phishing email, SMS, chat link, or QR code. The weaponized tool here is simply the malicious landing page described in the CVE record; no pre-auth foothold on your environment is required.
Conditions required:
  • Target uses Chrome on iOS
  • Installed version is older than 149.0.7827.53
  • User opens attacker-controlled content
Where this breaks in practice:
  • User must actually click and render the page
  • Only the iOS Chrome population is in scope
  • Modern email/web filtering may kill many delivery attempts before click-through
Detection/coverage: Traditional vulnerability scanners are weak here because this is a mobile client-app versioning problem, not an exposed network service. Detection is mostly via MDM/mobile app inventory.
STEP 02

Spoof browser trust signals

The crafted page abuses the inappropriate implementation to make UI elements or trust context appear misleading. The practical goal is to reduce user suspicion long enough to get credentials, MFA approval, or other sensitive input.
Conditions required:
  • Bug must be reachable from page content
  • Victim must interpret the spoofed UI as legitimate
Where this breaks in practice:
  • This is still a human deception play, not an automatic compromise
  • Defender-owned SSO branding, passkeys, and phishing-resistant MFA limit payoff even if the spoof lands
Detection/coverage: Network telemetry may only show ordinary browsing to a phishing domain. There is usually no clean exploit signature because the bug is about deceptive rendering, not a memory-corruption primitive.
STEP 03

Convert deception into account abuse

If the spoof is convincing enough, the attacker captures credentials or tricks the user into completing a sensitive action. The weaponized follow-on is a standard phishing workflow; the CVE is an *amplifier* for that workflow, not the breach mechanism by itself.
Conditions required:
  • Target enters credentials or approves an action
  • Attacker has infrastructure to receive and use captured data
Where this breaks in practice:
  • MFA, conditional access, impossible-travel detection, and identity-risk engines can still stop the actual account takeover
  • Impact is generally one user session or one account at a time, not broad host compromise
Detection/coverage: Identity telemetry is more useful than exploit telemetry here: suspicious logins, new device enrollments, impossible travel, and anomalous MFA prompts are the places to look.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence of active exploitation found in official sources reviewed. Not KEV-listed.
Proof-of-concept availabilityNo credible public PoC or weaponized exploit repo was identified in the reviewed sources. That fits the very low EPSS and the limited attacker payoff.
EPSS0.00022 (~0.022% probability over 30 days). That is near-floor territory and consistent with a low-value, low-automation client-side bug.
KEV statusAbsent from CISA's Known Exploited Vulnerabilities catalog as of this assessment.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N — remote delivery, no privileges, but user interaction is mandatory and impact is limited to low integrity.
Affected versionsGoogle Chrome on iOS prior to 149.0.7827.53.
Fixed version149.0.7827.53 or later. For iOS fleets, treat App Store rollout lag and MDM inventory staleness as the operational bottleneck.
Scanning / exposure dataShodan/Censys/FOFA-style exposure counting is not meaningful here. This is a mobile client application, not an internet-facing service you can reliably fingerprint from the outside.
Disclosure timelineThe CVE appeared in the NVD record on 2026-06-04 and received CISA-ADP enrichment on 2026-06-05. Google had already listed the CVE in the Chrome 149 security fixes published on 2026-06-02.
Reporter / sourceGoogle's Chrome release notes list it as reported by Google on 2026-04-13.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (2.9/10)

The decisive factor is that this is a user-interaction-dependent UI spoofing flaw in a client-side iOS browser, not a remotely exploitable code-execution bug. It can improve phishing conversion against individual users, but it does not provide a direct path to host takeover, lateral movement, or broad enterprise blast radius on its own.

HIGH Exploitability path and technical impact ceiling
MEDIUM Real-world exposure across managed iOS fleets

Why this verdict

  • Start below the 4.3 baseline: the CNA/ADP score assumes generic remote reachability, but in practice this is still a click-dependent deception bug with no direct code execution or data access.
  • User interaction compounds downward pressure: the attacker needs the victim to open a crafted page and then be fooled by the spoofed UI, which makes this a phishing enhancer rather than a self-driving exploit.
  • Exposure population is narrow: this is Chrome on iOS only, so it excludes desktop Chrome, Android Chrome, and non-Chrome iOS browsers; that sharply limits reachable enterprise population.
  • No internet-facing appliance surface: scanners and external attack-surface tools cannot meaningfully find this at scale because there is no listening service to hit; attackers must work one user at a time.
  • Threat intel is quiet: no KEV entry, no public exploitation evidence, and an EPSS of 0.00022 all argue against giving this front-of-queue status.

Why not higher?

There is no credible path here to arbitrary code execution, sandbox escape, privilege escalation, or fleet-wide compromise from the CVE alone. Even a successful exploit typically still needs the *separate* success condition of phishing the user into disclosing something useful.

Why not lower?

UI spoofing in a browser is not nothing: it can meaningfully improve the quality of phishing pages and suppress normal user suspicion. Because delivery is remote and unauthenticated, and because browsers sit in front of identity workflows, this deserves tracking and normal patching rather than being waved off as irrelevant.

05 · Compensating Control

What to do — in priority order.

  1. Enforce phishing-resistant MFA — Make stolen credentials less valuable by requiring passkeys, platform authenticator FIDO2, or equivalent phishing-resistant methods for high-value apps. For a LOW verdict there is no formal noisgate mitigation SLA; treat this as normal control hardening and keep it in your standing identity roadmap.
  2. Block unmanaged link paths for high-risk apps — Use conditional access, app protection, and managed-browser policies so sensitive SaaS access stays inside approved mobile app paths. This limits how much a spoofed browser page can convert into useful session theft; for LOW, handle as backlog hygiene rather than an emergency change.
  3. Inventory Chrome for iOS versions via MDM — Use Intune, Jamf, Workspace ONE, or equivalent to identify devices still below 149.0.7827.53 and verify app-update adoption. There is no mitigation SLA at this severity, but accurate inventory is what keeps low issues from quietly persisting forever.
  4. Tune identity detections for phishing fallout — Hunt for suspicious logins, impossible travel, MFA fatigue patterns, and anomalous device registrations tied to iOS/mobile user populations. This addresses the realistic downstream risk from the bug, which is account abuse, not host exploitation.
What doesn't work
  • A network vulnerability scan will not solve this; the bug lives in a mobile client app and does not expose a service you can probe remotely.
  • A WAF does not materially help if users browse directly to attacker-controlled domains outside your web applications.
  • Generic mobile AV claims are not a meaningful control for a UI spoofing bug; this is about deceptive rendering and user trust, not a traditional malware artifact.
06 · Verification

Crowdsourced verification payload.

Run this on an auditor workstation, CI runner, or MDM admin box against either a single version string or a CSV export from your mobile device manager. Example invocations: python3 check_cve_2026_11285.py --version 149.0.7827.45 or python3 check_cve_2026_11285.py --csv ios_chrome_inventory.csv --column AppVersion; no elevated privileges are required.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_cve_2026_11285.py
# Determine whether Google Chrome for iOS is vulnerable to CVE-2026-11285
# Fixed version: 149.0.7827.53
# Exit codes:
#   0 = all checked entries PATCHED
#   1 = one or more checked entries VULNERABLE
#   2 = UNKNOWN / input error / no valid rows

import argparse
import csv
import re
import sys
from typing import Optional, Tuple

FIXED = (149, 0, 7827, 53)


def parse_version(v: str) -> Optional[Tuple[int, int, int, int]]:
    if v is None:
        return None
    v = v.strip()
    m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', v)
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def classify(v: str) -> str:
    parsed = parse_version(v)
    if parsed is None:
        return 'UNKNOWN'
    if parsed < FIXED:
        return 'VULNERABLE'
    return 'PATCHED'


def check_single(version: str) -> int:
    result = classify(version)
    print(result)
    if result == 'PATCHED':
        return 0
    if result == 'VULNERABLE':
        return 1
    return 2


def check_csv(path: str, column: str) -> int:
    vulnerable = 0
    patched = 0
    unknown = 0
    valid_rows = 0

    try:
        with open(path, newline='', encoding='utf-8-sig') as f:
            reader = csv.DictReader(f)
            if not reader.fieldnames:
                print('UNKNOWN - CSV has no header row')
                return 2
            if column not in reader.fieldnames:
                print(f"UNKNOWN - column '{column}' not found. Available columns: {', '.join(reader.fieldnames)}")
                return 2

            name_col = None
            for candidate in ('DeviceName', 'device_name', 'Device', 'Name', 'SerialNumber', 'UDID'):
                if candidate in reader.fieldnames:
                    name_col = candidate
                    break

            for idx, row in enumerate(reader, start=1):
                version = row.get(column, '')
                status = classify(version)
                identifier = row.get(name_col, f'row-{idx}') if name_col else f'row-{idx}'
                print(f'{identifier}: {status} ({version})')

                if status == 'VULNERABLE':
                    vulnerable += 1
                    valid_rows += 1
                elif status == 'PATCHED':
                    patched += 1
                    valid_rows += 1
                else:
                    unknown += 1

    except FileNotFoundError:
        print(f'UNKNOWN - file not found: {path}')
        return 2
    except Exception as e:
        print(f'UNKNOWN - failed to read CSV: {e}')
        return 2

    print(f'SUMMARY: PATCHED={patched} VULNERABLE={vulnerable} UNKNOWN={unknown}')

    if valid_rows == 0:
        print('UNKNOWN')
        return 2
    if vulnerable > 0:
        print('VULNERABLE')
        return 1
    print('PATCHED')
    return 0


def main() -> int:
    parser = argparse.ArgumentParser(description='Check Chrome for iOS versions against CVE-2026-11285')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--version', help='Single Chrome for iOS version string, e.g. 149.0.7827.45')
    group.add_argument('--csv', help='CSV exported from MDM/app inventory')
    parser.add_argument('--column', default='AppVersion', help='CSV column containing Chrome version strings (default: AppVersion)')
    args = parser.parse_args()

    if args.version:
        return check_single(args.version)
    return check_csv(args.csv, args.column)


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

If you remember one thing.

TL;DR
Monday morning: do not hot-prioritize this over memory-corruption or server-side exposure. Update your MDM inventory query to find Chrome for iOS versions below 149.0.7827.53, roll the app update through your normal mobile maintenance channel, and keep an eye on identity telemetry for phishing fallout; for a LOW verdict there is noisgate mitigation SLA and noisgate remediation SLA here, so treat it as backlog hygiene and close it in your next routine mobile-app update cycle rather than burning emergency change capital.

Sources

  1. NVD CVE-2026-11285 detail
  2. Chrome Releases - June 2026 security fixes listing
  3. Chrome Stable for iOS Update (149.0.7827.45)
  4. Chromium issue 502090914
  5. CISA Known Exploited Vulnerabilities Catalog
  6. FIRST EPSS API documentation
  7. FIRST EPSS data and statistics
  8. MITRE CWE-451
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.