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.
3 steps from start to impact.
Deliver the lure page
- Target uses Chrome on iOS
- Installed version is older than 149.0.7827.53
- User opens attacker-controlled content
- 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
Spoof browser trust signals
- Bug must be reachable from page content
- Victim must interpret the spoofed UI as legitimate
- 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
Convert deception into account abuse
- Target enters credentials or approves an action
- Attacker has infrastructure to receive and use captured data
- 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
- 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.
The supporting signals.
| In-the-wild status | No public evidence of active exploitation found in official sources reviewed. Not KEV-listed. |
|---|---|
| Proof-of-concept availability | No credible public PoC or weaponized exploit repo was identified in the reviewed sources. That fits the very low EPSS and the limited attacker payoff. |
| EPSS | 0.00022 (~0.022% probability over 30 days). That is near-floor territory and consistent with a low-value, low-automation client-side bug. |
| KEV status | Absent from CISA's Known Exploited Vulnerabilities catalog as of this assessment. |
| CVSS vector | CVSS: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 versions | Google Chrome on iOS prior to 149.0.7827.53. |
| Fixed version | 149.0.7827.53 or later. For iOS fleets, treat App Store rollout lag and MDM inventory staleness as the operational bottleneck. |
| Scanning / exposure data | Shodan/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 timeline | The 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 / source | Google's Chrome release notes list it as reported by Google on 2026-04-13. |
Sources.
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.
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.
#!/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())