Test escape-surface page — for authorized device research only. Each card below is an independent probe; use one at a time and record what fires outside the sandbox.
Tests whether <input type=file> opens the native storage-access-framework file picker.
Tests whether a download invokes the system Download Manager notification/UI.
Download PDFTests whether window.print() reaches the system print spooler UI outside the WebView sandbox.
Tests whether market:// / https Play Store links hand off to Play Store / Galaxy Store app.
Open in StoreTests whether navigator.share() reaches the native Android share sheet (chooser intent).
Tests whether a login-shaped form triggers an autofill/password-manager suggestion bar with a Settings shortcut.
Tests whether target=_blank / window.open() escapes to the system default browser instead of staying in the CNA WebView.
Tests whether an embedded video iframe stays sandboxed, or whether fullscreen/"Watch on YouTube" triggers an app deep-link or browser escape.
Local video:
Tests whether a live <audio> stream triggers the system media-session notification/controls (lock screen, notification shade) and whether that surface exposes anything beyond play/pause.
Local audio:
Tests how the WebView resolves rare/legacy URI schemes it doesn't natively render — confirms whether scheme handling is deny-by-default or permissive-by-default, and surfaces any unexpected OEM/carrier app registrations.
Tests whether the Remote Playback API / Presentation API can summon the native system Cast device picker directly from page JS, without any browser-chrome menu interaction.
Tests whether beforeinstallprompt fires and can be triggered from page JS (Android's analogue to desktop "Create shortcut"). Requires HTTPS + manifest to qualify — likely a negative result on a plain HTTP captive portal page, which is itself informative.
Tests whether cookies, localStorage, sessionStorage, and IndexedDB are available, and whether values survive a page reload / re-navigation — indicates whether the captive portal WebView is properly isolated from the main browser profile. Quota estimate and empirical fill-test below reveal whether this origin shares a storage pool with the main browser profile (large/matching quota) or has its own small, ephemeral allocation (small quota).
Tests both IPv4 (127.0.0.1) and IPv6 ([::1]) loopback per port to infer open vs closed/filtered (fast refusal vs hang/timeout). Coarse signal only — confirms presence of a listener, not what it is. Cleartext-blocked WebViews or unrouted IPv6 loopback will show uniform results across all ports on that stack; treat that as inconclusive, not "all closed," unless a known-open port also reads uniform.
These input types hand off to native OS picker components rather than being drawn by the WebView itself — same "different system surface" category as the print dialog and file picker. Check each picker for any navigation chrome, settings shortcuts, or long-press context actions that shouldn't be reachable pre-auth.
Allocates memory aggressively to force an OOM condition in the WebView/host process. The interesting result isn't the crash itself — it's what screen the device lands on afterward. Does the setup wizard / captive portal correctly re-lock, or does recovery fall back to an unexpected activity or the home launcher? Run on a disposable test unit only — recovery may require a re-flash.
Fullscreen transitions have historically been a spot where system UI (status bar, notification shade pull-down) briefly re-exposes itself mid-transition. Rapid toggling stresses the transition state machine specifically, rather than the steady-state fullscreen view. Orientation lock mimics the YouTube-style expand-to-landscape behavior. The combined test at the bottom stacks orientation+fullscreen+memory pressure to see if the crash-recovery screen differs from the plain OOM test.
Not scriptable — the long-press "Share/Copy/Save" menu is native chrome UI with no JS trigger, unlike navigator.share() in card 8. Long-press each element below by hand and note whether Share appears, and what apps the resulting chooser lists.
Long-press this link: https://google.com
Long-press to select this text block: this is a paragraph of selectable text intended purely as a target for the text-selection toolbar, which on Android often shows a Share option alongside Copy and Search when a selection is active.
Fires intent:// URIs carrying crafted extras — embedded CRLF (log injection), oversized strings (layout/overflow spoofing), and null-byte-adjacent payloads (parser truncation) — against a target package/component you specify. Watch logcat and the receiving UI for anomalies, not just whether the intent resolves.
Loads a list of URIs/intents (one per line, e.g. from href_links.txt) and fires them sequentially with a delay between each — useful for sweeping exported activities/components you've enumerated via adb/jadx rather than testing one at a time. Optional: cross every line against the card 22 injection payloads (CRLF/oversized/null-byte) instead of firing it as-is. Caveat: if any entry causes real navigation (rather than an intent handoff), the loop stops since the page unloads — check the log to see how far it got.
Auto-loads href_links.txt from the same folder as this page on load. If that fails (e.g. opened as file:// with fetch blocked), use the file picker fallback below.
Renders every line from the loaded list (card 23) as an individual clickable link, so you can tap through one at a time by hand and watch what happens to each, instead of the automated timed sweep. Useful when a bulk run dies partway through and you want to resume manually from a known index, or when you specifically want to observe each navigation rather than just log it.
Tests whether permission-gated hardware and system APIs are reachable from page JS pre-auth, and — more importantly than whether they're merely available — whether the resulting native permission dialog is itself a system-level surface reachable outside the WebView sandbox. Each probe logs API presence, prompt outcome, and any error distinctly, since "not available" and "available but denied" are different findings.