On the web, the attacker is on the other side of a request. On mobile, the attacker may own the machine your code runs on — rooted, instrumented, decompiled at leisure. Threat-modeling a phone app means starting from that uncomfortable truth, and OWASP’s MAS project is the map for it.
A web app runs on a server you control and talks to a browser you don’t. A mobile app is the opposite: it runs on a device the user controls — and that user might be the attacker. Once your APK or IPA is installed, it can be pulled apart, decompiled, run on an emulator, hooked with Frida, and watched instruction by instruction. The “client” is no longer a black box behind a network boundary; it is open in the adversary’s hands. Threat modeling for mobile has to begin from that fact, not bolt it on at the end.
Why mobile threat modeling is different
Most threat-modeling habits come from server-side thinking: the code is on trusted infrastructure, the user is across a network, and the boundary between them is the place you defend. Mobile breaks every part of that assumption. The code ships to the user. The runtime is the user’s phone. And a meaningful fraction of those phones are rooted, jailbroken, emulated, or actively instrumented by the person holding them.
That single shift cascades into a different attack surface. You can no longer assume the binary is secret — anyone can decompile it. You can’t assume local storage is private — on a rooted device every file and database is readable. You can’t assume your own process memory is safe — a hooking framework can read keys out of RAM and rewrite return values on the fly. And you can’t assume the app is the only thing talking to your backend — once the API contract is reverse-engineered, a script can call it directly with no app at all.
On top of the hostile-runtime problem, mobile adds channels that simply don’t exist on the web: inter-process communication and exported components, deep links and custom URL schemes, the clipboard, on-device databases and keychains, push notifications, and a thick layer of platform APIs (biometrics, the keystore, location, camera). Every one of those is an entry point an attacker can poke from another app on the same device. So a mobile threat model has to enumerate a wider, weirder surface than a web app — and assume the device under it is compromised.
The mobile attack surface, end to end
Before you can model threats you have to see the whole surface. A mobile app isn’t one thing; it’s a chain — the device and OS, the app’s own IPC and exported components, local storage, the network in between, and the backend API on the far side. Each link is a place data can be read, tampered with, or replayed, and each sits inside a different trust boundary.
Notice where the trust boundaries fall. The dotted line between the app and the rest of the device matters because on a rooted phone that boundary is gone — the OS no longer protects your sandbox. The line between the device and the network matters because anyone on the same Wi-Fi (or running an interception proxy on their own phone) sits in the middle. And the line in front of the backend matters most of all, because it’s the one boundary you fully control: the server is the only place you can enforce a rule the client can’t lie about.
Enter OWASP MAS: the standard, the guide, the checklist
You don’t have to invent the controls yourself. The OWASP Mobile Application Security (MAS) project is the flagship body of work for exactly this, and it’s built from three pieces that reference each other:
MASVS — the Mobile Application Security Verification Standard. It’s the “what”: a stable, abstract set of security requirements grouped into eight control families. It deliberately says nothing about how to test, so it doesn’t rot every time a tool or OS version changes.
MASTG — the Mobile Application Security Testing Guide. It’s the “how”: a large manual of concrete tests, techniques, demos, and tooling for Android and iOS. MASTG tests are written to verify the MASVS controls (by way of an in-between weakness catalogue, MASWE — the Mobile Application Security Weakness Enumeration), so every test traces back to a requirement.
The MAS Checklist — the bridge. It lists each MASVS control alongside the MASTG tests that verify it, as a page and a downloadable spreadsheet, so you can run an assessment and track coverage and compliance against the standard.
The eight MASVS control groups
MASVS v2 organises everything into eight control families. Learn these eight names and you have the vocabulary for the entire mobile-security conversation — every finding you ever file will land in one of them.
| Control group | What it covers |
|---|---|
| MASVS-STORAGE | Secure storage of sensitive data on the device — data at rest. |
| MASVS-CRYPTO | Correct use of cryptography to protect sensitive data. |
| MASVS-AUTH | Authentication and authorization mechanisms the app relies on. |
| MASVS-NETWORK | Secure network communication — data in transit. |
| MASVS-PLATFORM | Secure interaction with the platform and other installed apps (IPC, deep links, WebViews). |
| MASVS-CODE | Security best practices for data processing and keeping the app and its dependencies current. |
| MASVS-RESILIENCE | Resilience against reverse engineering and tampering on a hostile device. |
| MASVS-PRIVACY | Controls to protect user privacy and data handling. |
Two of these are worth a second look because they’re where people get it wrong. MASVS-RESILIENCE is not a substitute for the others — root detection and obfuscation raise the cost of an attack, but they don’t make a hardcoded secret safe. And MASVS-PRIVACY, added in v2, reflects that “security” for a phone app now includes what data you collect, where it goes, and whether the user actually knows — not just whether it’s encrypted.
MASTG: turning controls into tests
A control like “the app stores sensitive data securely” is true or false only once you’ve actually looked. That’s the MASTG’s job. For each MASVS control it provides concrete, platform-specific procedures — pull the APK, inspect the shared preferences and SQLite databases, check the Android Keystore or iOS Keychain usage, intercept TLS and test for certificate pinning, decompile and grep for secrets — plus the techniques and tooling to do it.
The MASTG is organised so you can move in either direction: from a control down to the tests that verify it, or from a finding back up to the control it violates. The example below is the shape of a real assessment — a couple of quick storage and network checks against an Android build, the kind of thing a MASTG-STORAGE or MASTG-NETWORK test walks you through.
# MASVS-STORAGE: is sensitive data sitting in plaintext on disk? $ adb shell run-as com.example.app cat shared_prefs/auth.xml <string name="access_token">eyJhbGci...</string> # token in cleartext = STORAGE fail # MASVS-CODE / RESILIENCE: decompile and grep the binary for secrets $ apktool d app.apk -o out/ && grep -rinE 'api[_-]?key|secret|password' out/ out/smali/.../Config.smali: const-string v0, "AIzaSyHARDCODEDKEY..." # MASVS-NETWORK: does the app accept a proxy / forged cert? (pinning test) $ mitmproxy --mode transparent # route device traffic through the proxy traffic visible in cleartext # no pinning -> NETWORK weakness; pinned -> handshake fails # MASVS-PLATFORM: which components are exported and callable by other apps? $ grep -i 'android:exported="true"' out/AndroidManifest.xml
The OWASP Mobile Top 10, in one glance
If MASVS is the exhaustive standard, the OWASP Mobile Top 10 is the highlight reel — the ten risk categories that show up most often in real mobile apps. It’s a great starting point for a threat model because it tells you where to look first.
| Risk | What it means | Lands in |
|---|---|---|
| M1 | Improper Credential Usage — hardcoded or mishandled keys, tokens, passwords | STORAGE · CODE |
| M2 | Inadequate Supply Chain Security — compromised SDKs, libraries, build pipeline | CODE |
| M3 | Insecure Authentication / Authorization | AUTH |
| M4 | Insufficient Input / Output Validation | CODE · PLATFORM |
| M5 | Insecure Communication | NETWORK |
| M6 | Inadequate Privacy Controls | PRIVACY |
| M7 | Insufficient Binary Protections | RESILIENCE |
| M8 | Security Misconfiguration | PLATFORM · CODE |
| M9 | Insecure Data Storage | STORAGE |
| M10 | Insufficient Cryptography | CRYPTO |
Use the Top 10 to prime your thinking and MASVS to be thorough. The Top 10 tells you what usually goes wrong; MASVS makes sure you didn’t skip the categories that happen to be fine in most apps but catastrophic in yours.
How to actually threat-model a mobile app
Now the method. Threat modeling isn’t a tool you run; it’s four questions you answer about your own app, in order. The OWASP MAS material gives you the vocabulary and the control catalogue, and STRIDE gives you a systematic way to ask “what could go wrong” at every point in the diagram.
1. Identify the assets
What is actually worth stealing or breaking? For a mobile app this is usually: credentials and session tokens, encryption keys, PII (names, contacts, location, health or financial data), and business logic you don’t want bypassed (the “am I a paying user / did this payment clear” decisions). Write them down. Everything that follows is in service of protecting this list.
2. Map entry points and trust boundaries
Walk the surface from the previous diagram and list every place data crosses a boundary: the UI (inputs, the clipboard, screenshots), IPC and exported components (activities, services, content providers, broadcast receivers other apps can reach), deep links and custom URL schemes, local storage (preferences, SQLite, the keystore/keychain, cached files), the network, and the backend API. A trust boundary is anywhere the level of trust changes — between your app and another app, between the device and the network, between the client and the server.
3. Apply STRIDE at each boundary
For every entry point, ask the six STRIDE questions and see which threats are real for that spot:
| STRIDE | Mobile question to ask |
|---|---|
| Spoofing | Can another app or a script impersonate the user, the app, or the server? (fake deep link, replayed token, no cert pinning) |
| Tampering | Can the binary, local data, or in-memory state be modified? (repackaged APK, edited SQLite, Frida hook) |
| Repudiation | Can a security-relevant action happen with no trustworthy log on the server side? |
| Information disclosure | Can secrets leak — plaintext storage, logs, the clipboard, an unpinned TLS channel, an exported provider? |
| Denial of service | Can a crafted deep link or malformed input crash or lock the app? |
| Elevation of privilege | Can a client-side check (jailbreak gate, paywall, role) be bypassed because it’s only enforced on the device? |
4. Rate the risk, then map it to a control
For each threat, judge how likely it is and how bad the impact would be, and rank accordingly — a hardcoded production key (trivial to extract, total compromise) outranks a theoretical timing side-channel. Then, crucially, map every accepted threat to the MASVS control that addresses it. That mapping is what turns a brainstorm into an actionable backlog and a testable assessment.
Levels and profiles: how much hardening is enough
Not every app needs the same depth. A note-taking app and a banking app face very different adversaries, and the MAS project has always reflected that. Historically MASVS shipped three verification levels: L1 (a baseline every app should meet), L2 (defense-in-depth for apps handling sensitive data — banking, health), and R (resilience: binary protections and anti-tampering for apps facing targeted reverse engineering).
In the v2 refactor (2023), those levels were pulled out of MASVS so the standard could stay a clean, abstract set of controls. They didn’t disappear — they were reworked as MAS Testing Profiles and moved into the MASTG (aligned with NIST OSCAL). The logic: the same control can demand different tests depending on how much security the app needs, so the “how hard do we test this” decision belongs with the tests, not with the requirement. In practice you still reason the same way — baseline for everyone, defense-in-depth for sensitive data, resilience when the device itself is part of the threat model — you just pick a profile in the MASTG rather than a level in MASVS.
Putting MAS to work across the SDLC
The biggest mistake teams make is treating MASVS/MASTG as a final-gate audit. It pays off most when it runs through the whole lifecycle — the threat model written at design time becomes the test plan at build time becomes the sign-off at release.
At design, use MASVS and the Top 10 as input to the threat model — pick the control groups and profile that match the app’s risk, and bake the requirements into the architecture (server-side enforcement, what may live on the client, which platform APIs you’ll lean on). At build, fold the relevant MASVS controls into developer guidelines and wire lightweight checks into CI — static analysis for hardcoded secrets, a scan of exported components, a dependency check for the supply chain. At test, run the MASTG procedures for your chosen profile and tick off the MAS Checklist; pen-testers and automated tooling both speak this language. At release, the completed checklist is your evidence of coverage and your compliance artifact — and it feeds straight back into the next cycle’s threat model.
At a glance
| Piece | Role | You use it to… |
|---|---|---|
| MASVS | The verification standard (8 control groups) | define what must be true |
| MASWE | Weakness enumeration | name what can go wrong |
| MASTG | The testing guide (tests, techniques, demos) | prove whether a control holds |
| MAS Checklist | Control-to-test mapping spreadsheet | track coverage & compliance |
| Mobile Top 10 | Most common risk categories | prioritise where to look first |
| Profiles (L1/L2/R) | How deep to test, now in MASTG | match effort to the app’s risk |