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

Use after free 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 nasty pothole in the passenger lane, not a bridge collapse across your fleet

CVE-2026-10896 is a use-after-free in Chrome for iOS affecting versions before 149.0.7827.53. In plain English: a malicious page can trigger a memory-safety bug after a user browses to attacker-controlled content, potentially giving the attacker code execution in the context of the Chrome app.

The vendor-style 8.8/HIGH score overstates what most enterprise defenders should feel in practice. This is still a remotely reachable client bug, but it is UI-required, has no KEV listing or active exploitation evidence, carries a very low EPSS, and—most importantly—lands in Chrome on iOS, where Chrome rides on Apple’s browser stack and app sandbox rather than the full Blink/V8 desktop attack surface. That combination narrows reachable population and reduces post-exploit blast radius.

"Serious bug, but on iOS Chrome it lands inside Apple’s rails: one-click web attack, limited enterprise blast radius."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Deliver a crafted web lure

The attacker needs a phishing page, malicious ad, or redirected site that a target opens in Chrome for iOS. The weaponized tool here is simply a crafted HTML page / exploit page tuned to trigger the UAF in the iOS-specific Chrome path.
Conditions required:
  • Target uses Chrome on iPhone or iPad
  • Installed version is older than 149.0.7827.53
  • Attacker can get the target to open attacker-controlled web content
Where this breaks in practice:
  • This is not a server-side bug; each target must browse into it
  • Many enterprises standardize on Safari, not Chrome, on managed iOS
  • Managed mobile phishing defenses and Safe Browsing reduce click-through
Detection/coverage: Vulnerability scanners have weak direct visibility because this is a mobile client app. MDM/app inventory is the primary detection path.
STEP 02

Trigger the use-after-free

Once the page is loaded, the exploit attempts to force the freed object back into use and corrupt control flow. The weaponized tool is the browser exploit itself, likely JavaScript plus crafted DOM/page state rather than a reusable scanner module.
Conditions required:
  • Victim interaction reaches the malicious page
  • Bug survives iOS/Chrome memory-safety mitigations on the target build
Where this breaks in practice:
  • Mobile browser exploitation is reliability-sensitive across device models and iOS versions
  • Google restricted the bug details, which usually slows broad copycat weaponization
  • No public exploit repo or Metasploit-quality module is visible yet
Detection/coverage: Network tools rarely see the exploit reliably. Crash telemetry, mobile threat defense, and repeated Chrome crashes on managed devices may provide weak signals.
STEP 03

Gain execution inside app context

If exploitation succeeds, the attacker gets code execution in the Chrome app context on iOS. That matters, but it is not the same as unauthenticated device takeover across the estate; iOS app sandboxing and the WebKit-based architecture materially constrain what the initial bug buys.
Conditions required:
  • Exploit chain achieves reliable memory corruption on target device
  • iOS sandbox and platform mitigations are not further chained around
Where this breaks in practice:
  • Chrome on iOS is built atop WebKit/WKWebView constraints, not the full desktop Blink/V8 stack
  • App sandbox limits filesystem and system access absent another vulnerability
  • Turning app-context code execution into broad enterprise impact usually requires follow-on bugs or credential capture opportunities
Detection/coverage: EDR coverage on iOS is limited compared with desktop. Detection is mostly indirect via MDM health signals, app crash spikes, and mobile threat defense telemetry.
STEP 04

Convert foothold into meaningful damage

To matter operationally, the attacker still needs to steal session material, abuse browser-held data, or chain into a larger mobile compromise. The weaponized tool at this phase is an exploit chain, not this CVE by itself.
Conditions required:
  • High-value target browses in affected Chrome for iOS
  • Attacker has a useful post-exploit objective on a mobile app foothold
Where this breaks in practice:
  • Blast radius is typically one user on one device
  • Enterprise mobile browsers hold less sprawling local data than desktop endpoints
  • No evidence this bug is currently being chained in-the-wild
Detection/coverage: Identity telemetry, suspicious session reuse, and mobile threat defense are more useful than classic perimeter scanning.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known active exploitation in the material reviewed. User-provided intel says KEV: No, and the public Chrome release note does not state exploitation.
Proof-of-concept availabilityNo public PoC located from major channels during review. Chromium issue details appear restricted, which usually slows immediate commodity weaponization.
EPSS0.0008 (user-supplied), which is effectively background noise. FIRST describes EPSS as a daily estimate of exploitation probability over the next 30 days.
KEV statusNot listed in CISA KEV as of this assessment. That is a strong downward pressure on urgency versus internet-facing server bugs.
CVSS vector readoutCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H means remote, low complexity, no auth, but user interaction is required and scope stays unchanged. UI:R is the key reality check.
Affected versionsChrome on iOS before 149.0.7827.53. This is a client-side mobile-app population, not a server estate problem.
Fixed version149.0.7827.53 or later. On managed fleets, this usually means App Store / MDM-driven app update, not OS patching.
Exposure populationReachability is limited to users who both run Chrome on iOS and browse attacker content there. Many enterprises have smaller managed-iOS Chrome populations than Windows/macOS Chrome populations.
Scanning / internet exposureShodan/Censys/FOFA: not applicable in the usual sense. This is a mobile client app, so there is no meaningful internet-enumerable exposed service footprint to count.
Disclosure timelineUser-provided disclosure date is 2026-06-04; Google’s Chrome 149 desktop stable post is dated 2026-06-02 and references the CVE in the same release wave.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (6.4/10)

The decisive factor is platform friction: this is a Chrome-on-iOS client exploit, not a broadly exposed desktop or server bug, and successful exploitation lands inside Apple’s mobile browser and app-sandbox constraints. With UI required, no KEV, no visible public PoC, and very low EPSS, the practical enterprise risk is materially below the vendor-style 8.8 baseline.

HIGH Version range and fixed version
MEDIUM Assessment that iOS platform constraints reduce blast radius
MEDIUM Absence of public PoC / exploitation evidence at time of review

Why this verdict

  • Down from 8.8 because UI:R matters — the attacker needs the user to open malicious content in Chrome for iOS, so this is not wormable and not passively reachable.
  • Down because of attacker position and exposure fraction — this is a client-side mobile app bug affecting only the subset of your fleet that actually runs Chrome on iOS, not the full Chrome desktop estate.
  • Down because iOS constrains the landing zone — Chrome on iOS uses WebKit/WKWebView under Apple’s rules, and post-exploit impact is typically bounded to app context unless chained.
  • Down because threat intel is quiet — no KEV listing, no active exploitation cited, no public PoC found, and EPSS is extremely low.
  • Not lower because the primitive is still serious — remote memory corruption in a mainstream browser remains a real exploitation candidate against targeted users.

Why not higher?

A higher bucket would need an amplifier like active exploitation, broad external exposure, no-click reachability, or a desktop/server blast radius. This CVE has the opposite profile: user interaction, mobile-client-only population, and iOS platform constraints that make one-bug-to-fleetwide-impact much less plausible.

Why not lower?

It is still a remote browser memory-corruption bug in a very common app category, and successful exploitation can plausibly execute code in the app context. For high-risk users who routinely open links on managed iPhones, this is not ignorable backlog dust.

05 · Compensating Control

What to do — in priority order.

  1. Force-update Chrome on managed iOS — Use MDM/App Store controls to push 149.0.7827.53+ everywhere you manage Chrome on iPhone/iPad. Because the verdict is MEDIUM, there is no mitigation SLA; treat the update as normal remediation and finish within the 365-day remediation window, though most orgs should clear this far sooner because app updates are low-friction.
  2. Inventory Chrome-for-iOS population — Pull a current app-version report from your MDM so you know how many devices actually carry the exposure. Do this immediately so the issue stays scoped to real population instead of inheriting desktop-Chrome panic.
  3. Harden mobile web-risk controls — Keep Safe Browsing, DNS/web filtering, and mobile threat defense in enforcement mode to reduce delivery of malicious pages while the long tail updates. With a MEDIUM verdict there is no mitigation SLA, so use this as risk reduction while you work the normal patch cycle.
  4. Prioritize high-risk personas first — Executives, journalists, travelers, admins, and targeted users are the ones most likely to face bespoke mobile browser lures. Even without a mitigation SLA, patch these cohorts first because targeted mobile exploitation economics are different from broad enterprise spray.
What doesn't work
  • A WAF does not help; this is a client-side browser bug, not your web server getting attacked.
  • Classic internet vulnerability scanning will not surface this well because there is no externally exposed listening service to fingerprint.
  • Desktop-style EDR assumptions do not translate cleanly to iOS; detection is thinner and more indirect on mobile.
06 · Verification

Crowdsourced verification payload.

Run this on an auditor workstation against a CSV exported from your MDM/UEM containing at least one Chrome-for-iOS version column. Invoke it as python3 check_cve_2026_10896.py mdm_export.csv or python3 check_cve_2026_10896.py mdm_export.csv --version-column app_version. No admin rights are required; this is an inventory check, not a target-host script.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_cve_2026_10896.py
# Assess Chrome for iOS versions against CVE-2026-10896.
# Outputs per-row status: VULNERABLE / PATCHED / UNKNOWN
# Exit codes:
#   0 = all parsed rows patched
#   1 = one or more vulnerable rows found
#   2 = only UNKNOWN rows or input/problem error

import csv
import re
import sys
from argparse import ArgumentParser

FIXED_VERSION = (149, 0, 7827, 53)
DEFAULT_COLUMNS = [
    'app_version', 'version', 'chrome_version', 'appversion',
    'Application Version', 'App Version', 'Chrome Version'
]
DEVICE_COLUMNS = [
    'device', 'device_name', 'Device Name', 'serial', 'Serial Number',
    'udid', 'UDID', 'user', 'User', 'owner', 'Owner'
]


def normalize_version(value):
    if value is None:
        return None
    text = str(value).strip()
    if not text:
        return None
    m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', 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)


def compare_versions(a, b):
    return (a > b) - (a < b)


def pick_column(fieldnames, preferred=None, candidates=None):
    if preferred and preferred in fieldnames:
        return preferred
    if candidates:
        for c in candidates:
            if c in fieldnames:
                return c
    lowered = {f.lower(): f for f in fieldnames}
    if preferred and preferred.lower() in lowered:
        return lowered[preferred.lower()]
    if candidates:
        for c in candidates:
            if c.lower() in lowered:
                return lowered[c.lower()]
    return None


def main():
    parser = ArgumentParser(description='Check MDM-exported Chrome for iOS versions for CVE-2026-10896 exposure.')
    parser.add_argument('csvfile', help='Path to CSV exported from MDM/UEM')
    parser.add_argument('--version-column', help='Exact column name containing Chrome version')
    parser.add_argument('--device-column', help='Exact column name containing device identifier/name')
    args = parser.parse_args()

    try:
        with open(args.csvfile, 'r', encoding='utf-8-sig', newline='') as f:
            reader = csv.DictReader(f)
            if not reader.fieldnames:
                print('UNKNOWN: CSV has no header row', file=sys.stderr)
                sys.exit(2)

            version_col = pick_column(reader.fieldnames, args.version_column, DEFAULT_COLUMNS)
            device_col = pick_column(reader.fieldnames, args.device_column, DEVICE_COLUMNS)

            if not version_col:
                print('UNKNOWN: could not find a version column; use --version-column', file=sys.stderr)
                sys.exit(2)

            found_rows = 0
            vulnerable = 0
            patched = 0
            unknown = 0

            for idx, row in enumerate(reader, start=2):
                found_rows += 1
                device = row.get(device_col, '') if device_col else ''
                device = str(device).strip() if device else f'row_{idx}'
                raw_version = row.get(version_col)
                parsed = normalize_version(raw_version)

                if parsed is None:
                    print(f'{device},UNKNOWN,unparseable_version,{raw_version}')
                    unknown += 1
                    continue

                if compare_versions(parsed, FIXED_VERSION) < 0:
                    print(f'{device},VULNERABLE,{version_to_str(parsed)},fixed>={version_to_str(FIXED_VERSION)}')
                    vulnerable += 1
                else:
                    print(f'{device},PATCHED,{version_to_str(parsed)},fixed>={version_to_str(FIXED_VERSION)}')
                    patched += 1

            if found_rows == 0:
                print('UNKNOWN: CSV contains no data rows', file=sys.stderr)
                sys.exit(2)

            summary = f'SUMMARY vulnerable={vulnerable} patched={patched} unknown={unknown} fixed>={version_to_str(FIXED_VERSION)}'
            print(summary, file=sys.stderr)

            if vulnerable > 0:
                sys.exit(1)
            if patched > 0 and vulnerable == 0:
                sys.exit(0)
            sys.exit(2)

    except FileNotFoundError:
        print(f'UNKNOWN: file not found: {args.csvfile}', file=sys.stderr)
        sys.exit(2)
    except Exception as e:
        print(f'UNKNOWN: {e}', file=sys.stderr)
        sys.exit(2)


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

If you remember one thing.

TL;DR
Monday morning, scope this first: pull your MDM inventory for Chrome on iOS and identify anything below 149.0.7827.53. Because this landed at MEDIUM and there is noisgate mitigation SLA here, no mitigation SLA — go straight to the 365-day remediation window; under the noisgate remediation SLA, get all managed devices onto 149.0.7827.53+ within 365 days, but in practice you should push the mobile app update in the next normal cycle and clear high-risk users first this sprint.

Sources

  1. Chrome Releases: Stable Channel Update for Desktop (June 2, 2026)
  2. Chromium iOS Web Layer README
  3. Chromium Blog: Open-sourcing Chrome on iOS
  4. Apple App Store Review Guidelines
  5. Chrome Enterprise and Education: Previous release notes
  6. FIRST EPSS Model
  7. CISA Known Exploited Vulnerabilities Catalog
  8. Apple App Store: Google Chrome for iPhone/iPad
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.