Damn Vulnerable Mobile App
A single-codebase, intentionally vulnerable Flutter app that builds to real native iOS and Android binaries for mobile security training and pentest practice.
Warning
For authorized training and testing use only. DVMA is deliberately insecure. Do not deploy it to production infrastructure, publish it to app stores, or run it on devices holding real data. It exists so security engineers, pentesters, and students can practice against realistic mobile vulnerabilities in a controlled environment. You are responsible for using it only where you are authorized to do so. (Same convention as DVIA / DVWA / DVAC.)
DVMA ships 218 intentionally-vulnerable modules organized by OWASP MASVS category, each mapped to the OWASP Mobile Top 10 (2024), MASVS/MASTG, and CWE, plus a novel AI/ML assistant, agentic AI, and an AI × mobile (LLM-meets-IPC/WebView) module set mapped to the OWASP Top 10 for LLM/GenAI Applications (2025) and the OWASP Top 10 for Agentic AI Applications (2025).
Who it’s for: mobile security engineers, pentesters, and researchers who want a realistic native target to practice against; instructors and students learning MASVS/MASTG; and tool authors validating scanners against known, standards-mapped weaknesses. Contributors add new modules through a single registry entry (see Contributing).
📖 Docs site: the full, browsable catalog builds from a single source of truth, see Documentation.
New here? Start with the Getting Started guide — install Flutter, build the app, and install it on a device.
Quickstart (5 minutes)
Already have Flutter
set up? Clone, enable every module with the dev flavor, and run on a booted
emulator/simulator or a connected device:
Want to drive every module automatically instead of tapping through by hand?
The one-shot Appium harnesses build the app, run the full walk, and collect
on-device evidence (they need Node.js ≥ 18, e.g.
brew install node, for Appium/WebdriverIO):
Android (physical device or emulator; macOS/Linux):
iOS (Simulator; macOS):
First run needs Appium 2 and its drivers installed (a one-time
npm i -g appium + appium driver install), and the harness environment
variables are documented in
automation/README.md — the full setup and
run reference for the Appium / Espresso / XCUITest suites.
That’s the whole loop. For depth, device setup, build flavors, adding modules, rooting/jailbreak, and the full automation guide, head to the browsable docs site:
- Getting Started, install Flutter, build, install on a device/emulator, flavors, testing, automation
- Root & Jailbreak, root (Android/Magisk), jailbreak (iOS/Dopamine), and verifying extracted artifacts
- Vulnerabilities, the browsable module catalog (OWASP/MASVS/CWE mapped)
- Architecture, how the Flutter UI, native host, and companion attacker fit together
What’s inside
The vulnerability set is a floor, not a ceiling, the registry
(config/registry/, split into meta.yaml + one categories/<id>.yaml per
category) is an append-only catalog, so new items get a home under their
category without restructuring anything.
| Category | OWASP Mobile | Examples |
|---|---|---|
| Storage | M9 | plaintext prefs, Keychain/Keystore misuse, clipboard/log/screenshot leakage, external-storage & in-memory secrets, Keychain state-integrity manipulation, Keychain access-group authorization confusion, backup-archive integrity tampering, local security-state integrity tampering, auth-state rollback/restore, sensitive data in crash reports |
| Crypto | M10 | MD5/SHA1/DES/RC4/ECB, hardcoded keys, insecure RNG, weak KDF |
| Auth | M3 | weak sessions, bypassable biometrics, JWT alg:none, client-side authz, passkey/WebAuthn flaws (weak attestation, origin/RP-ID binding, credential exfiltration, fallback downgrade, assertion replay / sign-count, challenge reuse, UV-enforcement bypass, step-up bypass, credential-management authz, session fixation, third-party pairing authz), username enumeration, reset-token & backdoor, cross-app OTP leak, deep-link auth bypass, biometric result not bound to operation, credential-provider release authorization failure, multi-account isolation failure, identity-credential / mDL presentation not bound to session |
| Network | M5 | cleartext, weak TLS, bypassable pinning, accept-all trust manager |
| Platform | M4 | WebView JS-bridge RCE, deep-link hijack, exported components, zip-slip, FileProvider traversal, dynamic-code-loading RCE, overlay phishing, intent arg-injection RCE, deep-link→WebView nav, exported→arbitrary URL/activity, implicit-intent data leak, PendingIntent provenance confusion, in-app browser UI spoofing, cross-app scripting, GRANT_URI_PERMISSIONS abuse, custom-URL-scheme authorization, WKWebView untrusted-URL→local-file read, confused-deputy intent validation, SSRF via URL/media handler, QR→URL with no validation, proximity-transfer (AirDrop/Quick Share) unsafe parsing, Shortcuts symlink/path sandbox escape, exported-component state manipulation, ContentProvider filename traversal, App-Intent parameter → privileged action, content://→ContentResolver confused deputy, AccessibilityService privilege abuse, notification-listener authorization bypass, background-activity-launch abuse, clipboard unauthorized-write integrity tampering, clipboard → privileged-action injection, authorization based on mutable resource state, telephony / phone-account capability abuse, document-picker trusted-file confusion, system-surface → privileged App Intent exposure, cross-profile (work/personal) data & capability leakage, unauthenticated local/loopback service (+DNS-rebinding), dynamic (runtime) BroadcastReceiver exposure, privileged Service binding / Binder-interface exposure, Activity task-stack / affinity hijacking (StrandHogg-style), activity-alias exposure, platform-version security fallback, default-role / role-holder confusion, persistent URI-grant capability abuse, ClipData URI-grant leakage, file-descriptor capability leakage, ordered-broadcast result injection, app-widget / RemoteViews action injection, notification-action / trampoline authorization bypass, custom / signature permission squatting, Handoff / NSUserActivity injection, Universal-Link / AASA associated-domain confusion, App Clip invocation injection, Android capability-composition chain (notification→PendingIntent→receiver→Binder→transfer), iOS capability-composition chain (Universal Link→App Intent→security-scoped file→Contacts export) |
| Code quality | M7 | debuggable release, no obfuscation, leaked stack traces, CVE dep |
| Resilience | M7 | root/Frida/emulator/tamper detection with trivial bypasses, TOCTOU |
| Supply chain | M2 | malicious SDK, typosquatting, unsigned build artifacts, insecure Firebase/cloud config, missing/stale SBOM, silent SDK auto-update, dependency confusion, vulnerable-SDK exported component |
| Privacy | M6 | no-consent data access, no ATT prompt, PII in analytics, installed-app enumeration fingerprint, cross-app browser-history access, notification disclosure via alternate surface, lock-state confusion data exposure, privacy-control alternate-path bypass, system-assistant locked-device capability abuse |
| Input validation | M4 | unsafe deserialization, unvalidated intent extras, unsafe media/image decoding, deep-link regex DoS, protected-data access via input-validation confusion |
| AI/ML | M4 + LLM Top 10 | prompt injection (incl. invisible-unicode), RAG poisoning, hidden context exposure, on-device model extraction, key/model leakage |
| Agentic AI | M4 + Agentic Top 10 | agent memory poisoning, MCP/tool-description poisoning, confused-deputy tool misuse, insecure inter-agent comms, MCP open_url → arbitrary Android intent |
| AI × mobile | M4 + LLM Top 10 | untrusted mobile input (deep link/clipboard/QR) → LLM prompt, AI output → WebView XSS/local-file read, AI output → intent/URL navigation, AI output → tool/command injection, accessibility-tree → indirect prompt injection |
| Native bridge | M4 | JS-bridge callback-ID injection, cross-origin iframe → native bridge (no main-frame/origin check) → token theft, JS bridge exposing a privileged native API, QR/NFC → privileged action without confirmation, exported BroadcastReceiver data spoofing, WebView origin confusion → local-only IPC, WebView JS injection + SSL-validation bypass, embedded Mini-App secret exposure, WebView SOP/CSP disabled, shared-WebView mini-app isolation failure, provider-controlled metadata → plugin filesystem traversal (Flutter/RN/Cordova/Capacitor plugin boundary), WebView cleartext / mixed-content transport downgrade, WebView Safe Browsing disabled, WebView remote debugging enabled in production, WebView URL-loading (shouldOverrideUrlLoading) policy confusion |
| System provider | M4 | Mobile capability-broker abuse - an app that becomes a privileged system actor is a broker between an untrusted actor and a privileged capability: provider activation abuse (a11y / notification-listener / VPN / IME / device-admin / call-screening / phone-account / MediaProjection / credential-provider enablement as the boundary), MediaProjection / screen-capture authorization bypass, custom-keyboard / IME input interception, privileged IME event injection, companion-device pairing/capability confusion, Device Policy / MDM capability abuse, VPN provider trust-anchor / tunnel MITM, sensitive notification -> privileged AI processing, Assist / screen-context -> AI action exposure, App Group shared-container amplification, extension-activation != input-authorization, lock-screen control action authorization |
Documentation
The docs site is generated from the same registry (mirroring the ansible-security-scanner pipeline). Build it locally:
CI builds and deploys it to GitHub Pages on every push to main. The site is
generated from committed source, the module catalog from the registry
(config/registry/), the guides from docs/ (docs/getting-started/,
docs/device-access.md + docs/device-access/, docs/architecture.md +
docs/architecture/), and this README’s intro, so nothing drifts. The Manual
Testing checklist is generated from each module’s manual_test: registry field
(split per platform), so it never drifts from the catalog either.
For how the three pieces (Flutter UI, native Android host, and the companion
attacker app) fit together, and how every module produces a real,
device-extractable artifact, see
docs/architecture.md (published as the site’s
Architecture section, with a
system diagram plus child pages for the native bridges, companion attacker, and
real-artifact guarantee).