This is a bad lock on an interior door, not a busted front gate
CVE-2026-11287 is an Android Chrome navigation-policy bug, fixed in 149.0.7827.53, where a crafted HTML page can help an attacker *who already compromised the renderer process* bypass navigation restrictions. The affected population is Chrome on Android versions earlier than 149.0.7827.53; public release notes show Android 149.0.7827.48 shipped just before the fix, and older stable builds such as 148.0.7778.215 were also in the vulnerable range until the 149 branch picked up the corresponding security fixes.
The vendor-style 6.5 / MEDIUM score overstates enterprise urgency because it scores the bug like a remotely reachable web issue, while the plain-language description hides the real gate: the attacker must first land a separate renderer compromise. Chromium itself tagged the issue as *Low*, and that matches reality better for defenders managing fleets. This is a defense-in-depth break in an exploit chain, not a stand-alone foothold.
4 steps from start to impact.
Lure the user to attacker content
149.0.7827.53 to load attacker-controlled HTML. The delivery vehicle is trivial — any malicious site, ad slot, or redirect can host the page — but this CVE does nothing by itself at this stage.- Victim uses Chrome on Android
<149.0.7827.53 - Victim loads attacker-controlled web content
- User interaction is required by the CVSS model (
UI:R)
- Android-only population narrows exposure versus desktop Chrome
- Managed mobile fleets often auto-update through Google Play within about a day once policy conditions are met
- This step alone produces no impact from CVE-2026-11287
Chain in a separate renderer exploit
- A separate renderer compromise primitive is available
- Exploit reliability works on Android/ARM for the target build
- The attacker can execute the chain inside the browser sandbox context
- This is the decisive friction: prior compromise is mandatory
- No public PoC for this CVE was found in source review
- Modern browser mitigations and exploit reliability issues make chained browser exploitation non-trivial
Bypass navigation restrictions with crafted HTML
- Renderer is already compromised
- The exploit chain can exercise the vulnerable navigation path on Android
- The target build still enforces the old buggy policy logic
- Restricted Chromium issue details limit easy copycat weaponization
- Exact exploitability likely depends on specific navigation state and page structure
- Impact is bounded to what the bypass enables inside the broader chain
Turn the bypass into integrity impact
- A meaningful restricted-navigation target exists in the attack chain
- The attacker can capitalize on the bypass before the browser is restarted or updated
- No standalone confidentiality or availability impact is documented
- Blast radius is one browser instance on one device at a time unless paired with other bugs
- Enterprise risk depends heavily on whether you already care about mobile browser exploit chains
The supporting signals.
| In-the-wild status | No public exploitation evidence found in the reviewed sources, and it is not in CISA KEV as of 2026-06-06. |
|---|---|
| Public PoC status | No public PoC or weaponized repo was found in source review. The Chromium bug reference remains effectively opaque from public search, which raises friction for opportunistic attackers. |
| EPSS | 0.00019 from the user-supplied intel, which is extremely low. The exact percentile was not independently verified from an authoritative EPSS query during this assessment. |
| KEV status | Absent from the CISA KEV catalog; no KEV date applies. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N captures remote delivery and user interaction, but it does not price in the decisive prerequisite: prior renderer compromise. |
| Affected versions | Chrome on Android <149.0.7827.53. Public Android release notes show 149.0.7827.48 was released just before the fixed train. |
| Fixed versions | Upgrade Chrome on Android to 149.0.7827.53 or later. Google also notes Android releases inherit the corresponding desktop security fixes unless otherwise noted. |
| Disclosure timeline | Reported by Google on 2026-04-13 in Chrome release notes; desktop stable 149.0.7827.53 shipped on 2026-06-02; NVD published the CVE on 2026-06-04 and shows a CISA-ADP update on 2026-06-05. |
| Exposure / scanning reality | This is not an internet-scannable service. Shodan, Censys, and FOFA are basically irrelevant; exposure is whatever portion of your Android fleet is still below the fixed Chrome version. |
| Researcher / source | Reported by Google according to Chrome release notes; Chromium rated it Low even though the CISA-ADP CVSS entry shows 6.5 / MEDIUM. |
noisgate verdict.
The single biggest downgrading factor is that exploitation requires a pre-existing renderer compromise, which makes this post-exploitation inside the browser rather than a practical initial-access path. That sharply narrows the real attacker population, the reachable victim set, and the number of enterprise incidents this CVE will drive on its own.
Why this verdict
- Major prerequisite drag: the attacker must have already compromised the renderer process, so this CVE is chain-dependent rather than a front-door exploit.
- Population is narrower than generic Chrome CVSS implies: Android-only exposure cuts the enterprise blast radius relative to desktop/browser-wide scoring assumptions.
- No exploitation heat: no KEV listing, no public PoC found, and the supplied EPSS is near-zero, so there is no evidence this is attracting real-world attacker attention.
- Impact is bounded: published scoring shows integrity-only impact with no documented direct confidentiality loss, availability loss, or sandbox escape from this bug alone.
- Modern controls help at earlier stages: Safe Browsing, web filtering, Play auto-updates, and exploit mitigations mostly act on the precursor exploit stage, which is exactly where this chain is fragile.
Why not higher?
If this were a stand-alone remote browser exploit, a sandbox escape, or something already in active chains, the score would jump fast. But a vulnerability that only matters after renderer compromise is already one layer deep into an exploit path, and that is real-world downward pressure you should honor.
Why not lower?
It still sits in a highly exposed client surface — the mobile browser — and policy-bypass bugs can absolutely matter when paired with another browser flaw. So this is not IGNORE: it deserves routine patching and fleet verification, just not special-emergency treatment.
What to do — in priority order.
- Enforce Chrome auto-updates on managed Android — Use managed Google Play / Android Enterprise policy to make sure Chrome can update automatically and is not stuck behind charging, Wi-Fi, or idle constraints. For a
LOWverdict there is no SLA clock, but do this in the next normal mobile hygiene cycle so vulnerable149.0.7827.48and older builds age out quickly. - Inventory Chrome versions from MDM — Pull package/version data for
com.android.chromeand identify devices below149.0.7827.53. ForLOW, this is backlog hygiene rather than emergency response, but you want a clean target list before the next routine compliance review. - Reduce browser exploit-chain exposure — Keep Safe Browsing, web filtering, and malicious-site blocking enabled because they can disrupt the *precursor renderer exploit* this CVE depends on. That matters more than trying to detect this specific navigation bug, and it should remain a standing control for all managed devices.
- Prefer current stable channel only — Avoid version lag and unmanaged alternate channels on enterprise Android fleets unless testing requires them. For
LOW, align this during the next regular app-governance pass rather than treating it as a break-glass action.
- A WAF or perimeter IPS does not meaningfully solve this; the vulnerable surface is a local mobile browser processing attacker content, not an exposed enterprise web service.
- MFA is irrelevant to the browser bug itself; it may protect downstream accounts, but it does not stop a compromised renderer from exercising the vulnerable navigation path.
- Network scanning will not find this reliably because the issue lives in a client app version on Android devices, not in an internet-facing daemon.
Crowdsourced verification payload.
Run this on an auditor workstation against a CSV export from your MDM/EMM or asset inventory, not on the Android handset itself. Invoke it as python3 check_cve_2026_11287.py devices.csv --package-column package --version-column version with no special privileges; it outputs VULNERABLE, PATCHED, or UNKNOWN and returns exit code 1, 0, or 2 respectively.
#!/usr/bin/env python3
# check_cve_2026_11287.py
# Determine exposure to CVE-2026-11287 from an inventory CSV.
# Expected input: a CSV containing at least a package column and a version column.
# Default package name checked: com.android.chrome
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
import argparse
import csv
import re
import sys
from typing import List, Optional, Tuple
FIXED_VERSION = "149.0.7827.53"
DEFAULT_PACKAGE = "com.android.chrome"
def parse_version(v: str) -> Optional[Tuple[int, ...]]:
if v is None:
return None
parts = re.findall(r"\d+", v)
if not parts:
return None
return tuple(int(p) for p in parts)
def cmp_version(a: str, b: str) -> Optional[int]:
va = parse_version(a)
vb = parse_version(b)
if va is None or vb is None:
return None
max_len = max(len(va), len(vb))
va = va + (0,) * (max_len - len(va))
vb = vb + (0,) * (max_len - len(vb))
if va < vb:
return -1
if va > vb:
return 1
return 0
def main() -> int:
ap = argparse.ArgumentParser(description="Check inventory CSV for CVE-2026-11287 exposure")
ap.add_argument("csv_file", help="Path to inventory CSV export")
ap.add_argument("--package-column", default="package", help="CSV column containing package name (default: package)")
ap.add_argument("--version-column", default="version", help="CSV column containing installed version (default: version)")
ap.add_argument("--device-column", default="device", help="CSV column containing device identifier (default: device)")
ap.add_argument("--package-name", default=DEFAULT_PACKAGE, help="Android package name to evaluate (default: com.android.chrome)")
args = ap.parse_args()
vulnerable: List[str] = []
patched: List[str] = []
unknown: List[str] = []
found_rows = 0
try:
with open(args.csv_file, newline="", encoding="utf-8-sig") as fh:
reader = csv.DictReader(fh)
if reader.fieldnames is None:
print("UNKNOWN - CSV has no header row")
return 2
required = {args.package_column, args.version_column}
missing = [c for c in required if c not in reader.fieldnames]
if missing:
print(f"UNKNOWN - missing required column(s): {', '.join(missing)}")
return 2
for row in reader:
pkg = (row.get(args.package_column) or "").strip()
if pkg != args.package_name:
continue
found_rows += 1
device = (row.get(args.device_column) or f"row-{found_rows}").strip()
ver = (row.get(args.version_column) or "").strip()
result = cmp_version(ver, FIXED_VERSION)
if result is None:
unknown.append(f"{device}:{ver or 'NO_VERSION'}")
elif result < 0:
vulnerable.append(f"{device}:{ver}")
else:
patched.append(f"{device}:{ver}")
except FileNotFoundError:
print(f"UNKNOWN - file not found: {args.csv_file}")
return 2
except Exception as exc:
print(f"UNKNOWN - failed to process CSV: {exc}")
return 2
if found_rows == 0:
print(f"UNKNOWN - no rows found for package {args.package_name}")
return 2
if vulnerable:
print("VULNERABLE")
print(f"fixed_version={FIXED_VERSION}")
print(f"vulnerable_count={len(vulnerable)}")
print(f"patched_count={len(patched)}")
print(f"unknown_count={len(unknown)}")
for item in vulnerable[:50]:
print(item)
if len(vulnerable) > 50:
print(f"... {len(vulnerable) - 50} more vulnerable devices omitted")
return 1
if unknown and not patched:
print("UNKNOWN")
print(f"fixed_version={FIXED_VERSION}")
print(f"unknown_count={len(unknown)}")
for item in unknown[:50]:
print(item)
if len(unknown) > 50:
print(f"... {len(unknown) - 50} more unknown devices omitted")
return 2
print("PATCHED")
print(f"fixed_version={FIXED_VERSION}")
print(f"patched_count={len(patched)}")
print(f"unknown_count={len(unknown)}")
if unknown:
print("note=some devices had unparseable versions; review separately")
for item in unknown[:50]:
print(item)
if len(unknown) > 50:
print(f"... {len(unknown) - 50} more unknown devices omitted")
return 0
if __name__ == "__main__":
sys.exit(main())
If you remember one thing.
com.android.chrome, identify anything below 149.0.7827.53, and let managed Google Play/EMM updates clear it in the next normal mobile patch cycle; because this is LOW, there is no noisgate mitigation SLA and effectively no noisgate remediation SLA beyond backlog hygiene, so document the chain-dependent nature of the bug and close it during routine browser version maintenance rather than interrupting higher-value patch work.Sources
- NVD entry for CVE-2026-11287
- Chrome stable channel update for Desktop 149.0.7827.53
- Chrome for Android early stable 149.0.7827.48 release
- Chrome for Android stable 148.0.7778.215 release
- CISA Known Exploited Vulnerabilities Catalog
- Android Enterprise app update behavior
- Manage Chrome browser on Android devices
- Update Google Chrome on Android
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.