In short

This is a worked threat model for a mobile banking-style app: an Android and iOS client, a backend API, an OAuth 2.0 / OpenID Connect identity provider, a core ledger and push notifications, with payment initiation that requires step-up approval. Model it by drawing the data flows and trust boundaries, then walking STRIDE over each element and flow: token and data theft from the device, reverse engineering and repackaging, TLS interception, deep-link hijacking, overlay and screen-capture malware, SIM swap and OTP interception, transaction tampering and replay, approval fatigue, and backend API abuse. The mitigations are the platform keystores, attestation (Play Integrity, App Attest), transport hardening, device-bound transaction signing and, decisively, server-side authorization and limits. The controls map to OWASP MASVS v2.

  • The device is outside your trust boundary: a rooted or malware-infected phone can read anything the app can, so secrets and decisions cannot live only on the client.
  • Protect tokens and keys with the platform key stores (iOS Keychain and Secure Enclave; on Android, keys in the Android Keystore or StrongBox that encrypt the tokens), not in plain app files or shared preferences (MASVS-STORAGE, MASVS-CRYPTO).
  • Attestation (Play Integrity, App Attest) raises the cost of tampered clients and emulators but is a signal, not an authorization check; verify it server-side (MASVS-RESILIENCE).
  • Keep transport strict: TLS with the platform defaults, no cleartext, and pin or use the managed network config, weighing pinning's operational cost (MASVS-NETWORK).
  • Bind high-value actions to a device key and show the exact transaction in the approval, so phishing and approval fatigue can't move money (MASVS-AUTH).
  • Every authorization, limit and anti-fraud decision is enforced on the backend; client checks are UX, not security.

Verify it

  1. Walk each element and flow in the diagram against STRIDE and confirm every identified threat has a mitigation with an owner and a test.
  2. On a rooted device and an emulator, confirm the app's tokens and keys are not readable from files or shared preferences and that attestation fails closed server-side.
  3. Intercept traffic with a proxy and a user-installed CA and confirm the app refuses to connect (pinning or network config), then confirm a certificate rotation plan exists.
  4. Attempt to invoke the app through an unverified deep link and a second app claiming the same scheme, and confirm sensitive flows do not start.
  5. Confirm a payment approval shows the exact payee and amount, is bound to a device key, and that the backend rejects a replayed or tampered transaction and enforces limits regardless of the client.
  6. Test SIM-swap and OTP-interception scenarios against account recovery and step-up, and confirm they do not grant money movement on their own.
Applies to
  • Android Keystore/StrongBox, Network Security Config, App Links, Play Integrity API
  • iOS Keychain + Secure Enclave, App Transport Security, Universal Links, App Attest / DeviceCheck
  • OWASP MASVS v2
  • OWASP Mobile Top 10 2024

Mobile apps that handle money or other high-value actions on Android and iOS with a backend API and an identity provider. Platform APIs are current as of October 2026.

Part of
Workflow: Review a design

Fix it in your stack

Tested fixes: the vulnerable code, the fix, a plausible fix that still fails, and the regression tests that tell them apart.

Learning goals and prerequisitesAbout 26 minutes: 6 to read and 20 for the exercise

What you will learn

  • Draw the data flows and trust boundaries of a mobile banking app.
  • Enumerate STRIDE threats on the device, the transport and the backend.
  • Choose mitigations and map them to OWASP MASVS v2 controls.
  • Separate client-side hardening from the server-side checks that actually enforce decisions.

Before you start

Mobile and backend engineers and security reviewers doing a design review of a high-value mobile app.

  • Read a data-flow diagram and know what a trust boundary is.
  • Know the basics of mobile app, OAuth and API architecture.

Refresh first: Choose a threat modeling method and turn its findings into tests

Go to the guided practice

Data flows and trust boundaries of a mobile banking app

Untrusted deviceServer trust boundaryMobile appIdentity providerBackend APICore ledgerOIDC auth code + PKCE1Tokens, protected bythe key store1API call + access token2Read for this customeronly3Signed payment: payee, amount4Push: no sensitive content5Trust boundaryUntrusted input1Step, described below
  1. Sign inThe app runs an OAuth 2.0 / OIDC authorization-code flow with PKCE against the identity provider and protects the tokens with the platform key store (iOS Keychain; on Android, encrypted with a Keystore key).
  2. Call the APIThe app calls the backend over TLS with platform defaults and no cleartext, pinned where the rotation cost is acceptable, sending an access token; the backend authorizes every request.
  3. Read account dataThe backend reads balances and history from the core ledger, enforcing object-level authorization for the signed-in customer.
  4. Approve a paymentA payment requires step-up: the app signs the exact transaction with a device-bound key and the backend verifies it, enforcing limits and anti-fraud.
  5. NotifyThe backend sends a push notification with no sensitive content; opening it re-authenticates in the app.
The phone and the network are untrusted. Attestation and storage raise the cost on the device, but the backend enforces authorization, limits and transaction integrity.

Describe the system and its assumptions

The app is a retail banking client on Android and iOS. It signs the user in through an OAuth 2.0 / OpenID Connect provider using the authorization-code flow with PKCE, stores the resulting tokens in the platform keystore, and calls a backend API over TLS. The backend reads balances and transaction history from a core ledger and initiates payments, which require a step-up approval. Push notifications tell the user about activity but carry no sensitive content.

State the assumptions before modeling. The user's phone may be rooted, jailbroken, running in an emulator, or infected with malware that has accessibility or overlay permissions. The network may be hostile, including a proxy with a user-installed CA. The identity provider, backend and ledger are inside the bank's trust boundary and are modeled elsewhere; this model focuses on the client, the transport and the client-facing API.

List the elements, data and trust boundaries

The diagram above shows the flows. The table enumerates the elements and the trust boundary each sits behind, which is what STRIDE is applied to.

List the elements, data and trust boundaries
ElementData it handlesTrust boundary
Mobile appTokens, cached balances, device key, PIIUntrusted device
Keystore / KeychainRefresh token, device-binding keyHardware-backed on device
App-to-API channelAccess token, requests, responsesPublic network (untrusted)
Identity providerCredentials, tokens, MFA stateServer trust boundary
Backend APIAuthorization, limits, anti-fraudServer trust boundary
Core ledgerBalances, transactionsServer trust boundary
Push channelNotification metadata onlyThird-party, untrusted

STRIDE on the device

Most mobile-specific risk is on the device, where the attacker may fully control the platform. Walk STRIDE over the app and its stored data.

STRIDE on the device
Threat (STRIDE)ExampleMitigation (MASVS)
Information disclosureTokens or PII read from app files on a rooted deviceStore secrets in Keystore/StrongBox and Keychain+Secure Enclave; store the minimum (MASVS-STORAGE-1, MASVS-CRYPTO-1)
TamperingRepackaged or hooked app, or an emulatorPlay Integrity / App Attest verified server-side; obfuscation and anti-hooking as cost, not a gate (MASVS-RESILIENCE)
SpoofingOverlay or accessibility malware captures the PIN or an OTPFLAG_SECURE and screen-capture protection on sensitive screens; detect overlays (MASVS-PLATFORM-3)
Elevation of privilegeAnother app claims the custom URL scheme to hijack a flowVerified App Links / Universal Links, not custom schemes (MASVS-PLATFORM-1)
Information disclosureBalance shown in the app switcher or a screenshotHide sensitive content when backgrounded; block screenshots (MASVS-PLATFORM-3)

STRIDE on the transport

The channel between the app and the backend is on a public network. The main threats are interception and modification.

  • Information disclosure and tampering: a man-in-the-middle with a user-installed CA reads or changes traffic. Mitigate with TLS using platform defaults, no cleartext (Android Network Security Config, iOS App Transport Security), and certificate or public-key pinning where the operational cost of rotation is acceptable (MASVS-NETWORK-1, MASVS-NETWORK-2).
  • Spoofing: a phishing site imitates the app's web views. Keep authentication in the system browser or an authenticated web view, validate the OIDC issuer and audience, and never accept tokens the app did not request.
  • Replay: a captured request is resent. Use short-lived access tokens, TLS, and per-transaction signatures with a nonce for money movement (below).

STRIDE on the client-facing API

The backend is where decisions are actually enforced, so client-reachable API threats matter even though the server is inside the trust boundary. The mobile client can be fully controlled by an attacker, so treat every request as attacker-shaped.

  • Elevation of privilege / information disclosure: broken object-level authorization lets one customer read or move another's money by changing an id. Enforce object-level authorization on every request against the authenticated subject (API1:2023); see /domains/appsec/authorization/object-level-authorization/.
  • Tampering with business flows: automated abuse of a sensitive flow such as transfers or rewards. Apply velocity and amount limits and anti-fraud server-side (API6:2023).
  • Spoofing: a stolen or replayed token. Bind tokens to the client where possible, keep them short-lived, and require step-up for high-value actions.
  • Repudiation: a disputed payment. Keep an append-only audit log of the signed transaction and the approval.

Account takeover paths that bypass the app

Not every attack goes through the app. SIM swap lets an attacker receive SMS one-time codes, and OTP interception and phishing capture codes in transit, so SMS OTP is a weak second factor for authorizing money movement. Model recovery and step-up explicitly: prefer passkeys or a device-bound key over SMS, require re-authentication for sensitive changes, and ensure that compromising the phone number alone does not grant payment authority. The account-takeover guide at /domains/identity-crypto/authentication/mfa-account-takeover/ covers these paths.

Bind money movement to the device and the transaction

The decisive control against phishing, malware and approval fatigue is to bind a high-value action to a key on the device and to the exact transaction. When the user approves a payment, the app signs a structure containing the payee, amount and a server nonce with a key in the Keystore or Secure Enclave (a passkey/FIDO credential works well), and the approval prompt shows the payee and amount so the user is approving what they see. The backend verifies the signature, checks the nonce to stop replay, and enforces limits and anti-fraud regardless of what the client claims. A blind push-approval that says only approve or deny trains users to tap approve; show the details.

Record residual risk and assumptions

A threat model is honest about what remains. On a fully compromised device, the attacker can observe the user and the app in real time; device-binding and server-side limits contain the damage but do not eliminate it. Attestation can be bypassed by determined attackers, so it reduces fraud volume rather than guaranteeing an authentic client. Pinning protects the channel but adds a rotation obligation; a bad rotation can brick the app, so plan it. Write these down with the compensating controls (limits, anti-fraud, monitoring) and revisit them when the platform or the feature set changes.

Keep the model current

Re-run the model when the architecture changes: a new high-value feature, a new third-party SDK, a change to the identity provider, or a platform API deprecation. Track each threat to a control, a MASVS requirement and a test, and tie the tests into CI (the methods guide at /domains/appsec/threat-modeling/threat-modeling-methods/ covers per-story threat modeling). Map deep dives to OWASP MASVS v2 and the MASTG test cases, and watch the OWASP Mobile Top 10 2024 for new classes.

Guided practice

You are reviewing the mobile banking app before a release that adds instant payments. The design notes below are from the team. For each, name the STRIDE category and MASVS area, say what is wrong, and give the fix.

Supplied scenario material
Plain text
N1  The refresh token is stored in Android SharedPreferences and an iOS plist file "for reliability."
N2  Payments are approved by an SMS one-time code sent to the registered number.
N3  The app opens a payment confirmation via myapp://pay?to=...&amount=... (a custom scheme).
N4  The app disables certificate validation in debug builds, and the debug flag ships enabled.
N5  The approval screen says "Approve this payment?" with Approve / Deny buttons and no details.
N6  The backend checks that the account id in the request belongs to a valid customer, then returns the data.
N7  Account balances are visible in the app switcher thumbnail.
  1. 1. Fix token storage

    Classify N1 and give the fix.

    Expected result and reasoning

    Information disclosure, MASVS-STORAGE/CRYPTO: SharedPreferences and plist files are readable on a rooted/jailbroken device and in backups. Encrypt the refresh token with an Android Keystore key (StrongBox if available), keep it in the iOS Keychain with Secure Enclave protection, and keep access tokens short-lived in memory.

  2. 2. Replace SMS approval

    Classify N2 and give the fix.

    Expected result and reasoning

    Spoofing, MASVS-AUTH: SMS OTP is defeated by SIM swap and interception. Approve payments with a device-bound signature (passkey/FIDO or a Keystore/Secure Enclave key) over the exact transaction, verified server-side.

  3. 3. Fix the deep link

    Classify N3 and give the fix.

    Expected result and reasoning

    Elevation of privilege / spoofing, MASVS-PLATFORM-1: a custom scheme can be claimed by another installed app to hijack the flow. Use a verified Android App Link / iOS Universal Link, and never start a payment flow from an unauthenticated deep link.

  4. 4. Fix TLS

    Classify N4 and give the fix.

    Expected result and reasoning

    Information disclosure / tampering, MASVS-NETWORK: shipping with validation disabled allows man-in-the-middle. Never disable validation in shipped builds; strip debug flags in release, enforce the Network Security Config / ATS, and pin with a rotation plan.

  5. 5. Fix the approval and the authorization

    Classify N5 and N6 and give the fixes.

    Expected result and reasoning

    N5 is approval fatigue (MASVS-AUTH): show payee and amount and bind the signature to them. N6 is broken object-level authorization (API1:2023): checking that the account is a valid customer is not checking it belongs to the authenticated caller; authorize the object against the signed-in subject.

Your deliverable: A threat table for N1-N7 with STRIDE category, MASVS area, the flaw, and the fix, plus the residual risks and the tests that would confirm each fix.

The exercise reasons about design notes on paper. It does not run the app on real devices, test attestation bypass, or exercise the backend; a real review needs device testing, a proxy interception test, and backend authorization tests.

Save a draft on this device to resume later. Automatic saving begins after you choose Save. Drafts are never sent by this application; use synthetic data.

No draft saved on this device yet.

Sources & further reading

The standards, specifications and documentation behind the guidance above. Each is the evidence for a claim on this page; consult it for detail beyond the defaults and versions listed here.

  1. OWASP MASVS v2 (Mobile Application Security Verification Standard)
  2. OWASP Mobile Application Security Testing Guide (MASTG)
  3. OWASP Mobile Top 10 (2024)
  4. Android: Play Integrity API
  5. Android: Network Security Configuration
  6. Android: verify App Links
  7. Apple: establishing your app's integrity (App Attest / DeviceCheck)
  8. Apple: supporting Universal Links in your app
  9. OWASP API Security Top 10 2023: API1 Broken Object Level Authorization
  10. Microsoft STRIDE threat model

Reference information

SDLC phase
Design
OWASP MASVS v2 controls
MASVS-STORAGE-1 · MASVS-CRYPTO-1 · MASVS-AUTH-2 · MASVS-AUTH-3 · MASVS-NETWORK-1 · MASVS-NETWORK-2 · MASVS-PLATFORM-1 · MASVS-PLATFORM-3 · MASVS-RESILIENCE-1

Download this guide as Markdown