You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An intentionally vulnerable Android application for learning and practising Android mobile security testing. Every vulnerability is deliberately introduced — each class carries a comment explaining what is broken, why it matters, and what the fix looks like.
setAllowFileAccessFromFileURLs(true) — JS loaded from a file:// URL can fetch() any file on the device
javascript-interface-rce
WebViewActivity
addJavascriptInterface exposes exec(String) and readFile(String) to any JS in the WebView
cookie-manager-cross-origin
WebViewActivity
CookieManager.setAcceptThirdPartyCookies(true) — third-party iframes receive session cookies
http-fetch-ssrf-android
WebViewActivity
JS bridge fetch() method issues arbitrary HTTP requests server-side using the app's credentials
jwt-token-fragment-leak
OAuthCallbackActivity
Access token appended to a URL fragment and passed to WebViewActivity, where it lands in the fragment and may be forwarded to subresources
Intent and IPC
ID
Location
Description
intent-redirection-arbitrary-activity-launch
IntentRedirectorActivity
getParcelableExtra("next_intent") forwarded to startActivity() without component validation — any exported component reachable
parcelable-redirection
IntentRedirectorActivity
Caller-supplied Parcelable deserialized before the caller's identity is checked — gadget-chain entry point
stream-uri-read
StreamUriActivity
openInputStream called on a URI from getIntent() with no allowlist — attacker reads private content provider data
file-write-via-intent
FileWriteActivity
Filename and content taken from intent extras and written to the filesystem without path canonicalization
reflection-class-loading-intent
ReflectionActivity
Class.forName(intent.getStringExtra("class_name")) — attacker triggers static initializers or constructor side-effects on any class
cross-app-classloader-parcelable
CrossAppClassLoaderActivity
Parcelable deserialization using the caller app's ClassLoader (Valsamaras BH EU 2024) — attacker-controlled class instantiated
Content providers
ID
Location
Description
content-provider-path-traversal
VulnContentProvider
openFile() builds a path from the URI segment without normalization — ../ traverses outside the intended directory
content-resolver-sql-injection
VulnContentProvider
query() concatenates the caller's selection argument directly into an SQL query — full SQL injection
file-provider-overbroad-root-path
FileProviderActivity, file_paths.xml
FileProvider <root-path path="/" /> — any file on the device shareable via a content URI
provider-grant-escalation
ProviderGrantActivity, ShareSecretActivity
takePersistableUriPermission retained after the granting activity finishes; direction B hands callers a persistent read grant on the private SecretProvider
Session token, login status, and OAuth tokens sent in implicit broadcasts with no android:permission — any app receives them
sticky-broadcast-eavesdropping
StickyBroadcastActivity, BootReceiver
sendStickyBroadcast persists OAuth tokens in system memory; any app calling registerReceiver(null, filter) receives the last value immediately
PendingIntent
ID
Location
Description
mutable-pending-intent-hijack
NotificationActivity, AlarmService
FLAG_MUTABLE PendingIntent built from a target intent — receiver can modify extras or action before it fires; Tier 2 variant uses an empty base intent, allowing a NotificationListenerService to fill in all fields and steal a URI grant on SecretProvider
Cryptography
ID
Location
Description
android-crypto-misuse
CryptoActivity
AES/ECB mode; hardcoded static IV for CBC; password used directly as key material without KDF; MD5 for integrity; SecureRandom seeded with a fixed value
android-keystore-without-auth-binding
KeystoreActivity
KeyStore key generated without setUserAuthenticationRequired(true) — usable without biometric or PIN, survives screen-lock bypass
Network
ID
Location
Description
hostname-verifier-bypass
NetworkActivity
Custom HostnameVerifier returns true for all hostnames — MITM with any certificate accepted
nsc-trust-anchors-override
network_security_config.xml
User-installed CA certificates trusted for all domains; cleartextTrafficPermitted="true" for api.vulnlabapp.example.com
Authentication and session
ID
Location
Description
mobile-oauth-intent-redirect
OAuthCallbackActivity
OAuth authorization code and tokens logged to Logcat — readable by any app with READ_LOGS; state parameter never validated (CSRF)
logging-pii-in-release
LoginActivity
Log.d emits email, password, and session token in the release build
Deep links and URL schemes
ID
Location
Description
app-link-autoverify-false
DeepLinkActivity
android:autoVerify intentionally omitted from the https:// intent filter — any app can register the same scheme and intercept the link
nav-component-complementary-argument
NavHostActivity
Navigation Safe Args destination receives an argument from the deep-link URI without validation — arbitrary fragment or destination reachable
Code execution
ID
Location
Description
command-injection-android
CommandInjectionActivity
User input concatenated into Runtime.getRuntime().exec() — shell command injection
dynamic-code-loading
DynamicCodeActivity
DexClassLoader loads a .dex from a caller-supplied /sdcard/ path — arbitrary code execution
cordova-ionic-bridge-rce
CordovaBridgeActivity
Fake Cordova exec() bridge exposes System.exec and FileSystem.readFile to any JS loaded in the WebView
react-native-bridge-inspection
ReactNativeBridgeActivity
Simulated @ReactMethodSystemModule.exec and AuthModule.getStoredToken callable from JS — shell execution and token exfiltration
Anti-analysis and detection
ID
Location
Description
root-detection-bypass-methodology
DetectionActivity
Filesystem, su binary, and package-manager checks — all bypassable with Frida hooks
frida-detection-bypass-methodology
DetectionActivity
/proc/self/maps scan for frida and port 27042 probe — bypassable by patching the scan
anti-frida-anti-debug-methodology
DetectionActivity
TracerPid read from /proc/self/status and ptrace(PTRACE_TRACEME) self-attach check
Build and signing
ID
Location
Description
debuggable-release-build
build.gradle
debuggable true in the release build type — ADB debugging and Frida attach work without a rooted device
no-obfuscation
build.gradle
minifyEnabled false in release — full class and method names visible in apktool or jadx output
janus-v1-signing
JanusInfoActivity
APK signed with v1 only (no v2/v3) on devices running Android 5.0–7.x — Janus vulnerability allows prepending a DEX to the APK without invalidating the signature
Miscellaneous
ID
Location
Description
fragment-injection
VulnPreferenceActivity
PreferenceActivity.isValidFragment() returns true for all fragments — attacker launches any Fragment class as a privileged activity
task-hijacking-strandhogg
TaskHijackActivity
No taskAffinity or launchMode restriction on the main task — an attacker app with a matching affinity and singleTask intercepts the next launcher tap
com.vulnlab.app.SENSITIVE_ACTION declared with protectionLevel="normal" — any installed app can request and receive this permission without user confirmation
play-integrity-bypass
PlayIntegrityActivity
Simulated Play Integrity verdict decoded locally from a static token with no signature verification — verdict trivially spoofed
Disclaimer
This application is for educational and security research purposes only. All hardcoded values (bundle IDs, API keys, endpoints) are fictional. Do not install on a production device or distribute outside a lab environment.