Mobile Threat Model — OWASP MASVS / MASTG

A mobile app is not code on a server you control — it is a binary running on hardware in the user's (or attacker's) hands. That single fact rewrites the threat model: storage, IPC, the network, the platform, and the backend are all in play, and the device itself is part of the adversary. This is how to think about mobile risk, and how OWASP's MASVS and MASTG turn that thinking into a repeatable, level-based assessment.

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.

15 min read Visual + examples MASVS / MASTG

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 threat-modeling premiseTreat the device as hostile by default. Sensitive logic, secrets, and trust decisions that must stay trustworthy belong on the server. Anything that has to live on the client should be protected as if an attacker is already reading it — because, in the worst (and entirely realistic) case, they are.

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.

How the three fit togetherRead it as a chain: a weakness (MASWE) violates a control (MASVS), and a test (MASTG) proves whether that control holds. MASVS is the requirement, MASTG is the procedure, MASWE is the catalogue of what can go wrong, and the checklist is the spreadsheet that ties them together for a single app.

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 groupWhat it covers
MASVS-STORAGESecure storage of sensitive data on the device — data at rest.
MASVS-CRYPTOCorrect use of cryptography to protect sensitive data.
MASVS-AUTHAuthentication and authorization mechanisms the app relies on.
MASVS-NETWORKSecure network communication — data in transit.
MASVS-PLATFORMSecure interaction with the platform and other installed apps (IPC, deep links, WebViews).
MASVS-CODESecurity best practices for data processing and keeping the app and its dependencies current.
MASVS-RESILIENCEResilience against reverse engineering and tampering on a hostile device.
MASVS-PRIVACYControls 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.

MASTG-style spot checks (Android)
# 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.

RiskWhat it meansLands in
M1Improper Credential Usage — hardcoded or mishandled keys, tokens, passwordsSTORAGE · CODE
M2Inadequate Supply Chain Security — compromised SDKs, libraries, build pipelineCODE
M3Insecure Authentication / AuthorizationAUTH
M4Insufficient Input / Output ValidationCODE · PLATFORM
M5Insecure CommunicationNETWORK
M6Inadequate Privacy ControlsPRIVACY
M7Insufficient Binary ProtectionsRESILIENCE
M8Security MisconfigurationPLATFORM · CODE
M9Insecure Data StorageSTORAGE
M10Insufficient CryptographyCRYPTO

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:

STRIDEMobile question to ask
SpoofingCan another app or a script impersonate the user, the app, or the server? (fake deep link, replayed token, no cert pinning)
TamperingCan the binary, local data, or in-memory state be modified? (repackaged APK, edited SQLite, Frida hook)
RepudiationCan a security-relevant action happen with no trustworthy log on the server side?
Information disclosureCan secrets leak — plaintext storage, logs, the clipboard, an unpinned TLS channel, an exported provider?
Denial of serviceCan a crafted deep link or malformed input crash or lock the app?
Elevation of privilegeCan 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.

Findings map straight back to MASVS“Access token in plaintext SharedPreferences” → MASVS-STORAGE. “No certificate pinning” → MASVS-NETWORK. “Exported activity launches with attacker-controlled deep link” → MASVS-PLATFORM. “Hardcoded API key in the binary” → MASVS-CODE / STORAGE. “Paywall enforced only in the app” → MASVS-AUTH. Once a threat carries a control label, the MASTG tells you exactly how to test the fix.

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.

MAS in one sentence per phaseDesign: threat-model with MASVS + Top 10, pick a profile. Build: encode controls in guidelines + CI checks. Test: run MASTG procedures, complete the MAS Checklist. Release: checklist is your coverage and compliance evidence, then loop.

At a glance

PieceRoleYou use it to…
MASVSThe verification standard (8 control groups)define what must be true
MASWEWeakness enumerationname what can go wrong
MASTGThe testing guide (tests, techniques, demos)prove whether a control holds
MAS ChecklistControl-to-test mapping spreadsheettrack coverage & compliance
Mobile Top 10Most common risk categoriesprioritise where to look first
Profiles (L1/L2/R)How deep to test, now in MASTGmatch effort to the app’s risk
TL;DRMobile threat modeling starts from a brutal premise: the app runs on a device the attacker may fully own — rooted, instrumented, decompiled — so the client cannot be trusted and anything that must stay true lives on the server. Map the wider surface (UI, IPC and exported components, deep links, local storage, network, backend), identify your assets (creds, tokens, keys, PII, business logic), run STRIDE at each trust boundary, rate the risks, and map every finding to a MASVS control. OWASP MAS gives you the whole toolkit: MASVS (the eight-group standard), MASTG (concrete tests), MASWE (the weakness catalogue), the MAS Checklist (coverage), the Mobile Top 10 (where to start), and profiles (how hard to test). Wire it through the SDLC — design, build, test, release — and the threat model you wrote on day one becomes the sign-off you ship with.
Reactions

Related Articles