Skip to content

Cybersecurity Engineering Handbook / Chapter 50

Mobile Application Security Playbook

Secure mobile applications by treating the device as untrusted while protecting local data, sessions, API communication, and release integrity.

A manager opens an expense app from a push notification and approves a reimbursement. The app unlocks with a fingerprint, reads an access token from protected storage, and sends the approval over TLS. Each step can work exactly as designed while the reimbursement is still unsafe.

The notification may disclose an employee’s name on a locked screen. The deep link may accept a substituted expense id. Malware may invoke the approval from another app. A modified binary may change the amount displayed to the manager. A captured token may be replayed from a different device. An old release may call a retired route that no longer receives careful review.

The server therefore needs to decide from trusted state which manager may approve which expense, for what amount, in its current workflow state. The device can protect data and make abuse harder; it cannot hold durable authority over money, entitlement, or access.

Mobile application trust boundary diagram showing an untrusted client, TLS to server enforcement, trusted controls, and a local storage decision tree for public cache, sensitive user data, access token, and app secrets.
Protect data on the client, but keep authorization and business-rule enforcement on the server.

Start with the client an attacker receives

A mobile application is executable code delivered outside the organization’s control. An attacker can inspect its package, strings, resources, local database, and network behavior; instrument functions; alter branches; automate screens; and call the backend without using the interface. Rooted or jailbroken devices make some of this easier, but an ordinary device, a test proxy, a copied token, or a reconstructed API request may be enough.

For the expense approval, write the server’s claim without referring to a button:

This authenticated manager may approve this expense, for the amount and payee held in authoritative records, while it awaits this manager’s approval, once.

Every client value is evidence offered to that decision, not the decision itself. A hidden expense id, disabled approval button, local role flag, biometric success, app-attestation result, and unmodified binary can all inform risk. None proves the claim. The API must resolve the expense in the manager’s organization, authorize the relationship and action, read the authoritative amount and payee, enforce the state transition, and make repetition harmless.

This separation also defines useful failure behavior. A compromised device may expose data that the user was allowed to cache. It should not let the attacker invent a reimbursement, approve another team’s expense, change a payee, or turn a presentation-layer flag into server entitlement.

Decide what may persist on the device

Local storage is a product decision with a security consequence. Begin with the data’s purpose, sensitivity, lifetime, offline requirement, and deletion behavior rather than choosing a database and adding encryption later.

Public, reconstructible cache data may use ordinary application storage if tampering cannot create authority. Sensitive user data needs platform-backed protection appropriate to its lifetime and must be scoped to the signed-in user and device. Access and refresh tokens belong in approved OS secure storage, with the shortest lifetime compatible with the session design. Material that grants broad backend authority does not belong in the app at all.

The expense app might cache merchant names and draft receipt images so a traveller can work offline. That choice creates obligations: exclude the cache from unprotected backups, protect files and search indexes, prevent one account from inheriting another’s drafts, define what logout and remote account removal erase, and reconcile offline edits before they affect authoritative records. Encryption reduces exposure from copied storage; it does not make a value trustworthy after the application decrypts it.

Do not embed private keys, signing keys, database credentials, privileged service tokens, hidden entitlement flags, or long-lived backend secrets in the binary. Obfuscating or splitting a static secret changes extraction cost, not its nature. If the backend needs evidence that a request likely came from a legitimate installation, use a narrowly scoped installation credential or platform attestation as one signal, then contain failure with server-side authorization, rate limits, rotation, and abuse detection.

Deletion must follow every copy. Logout may need to revoke the server session and clear tokens, databases, files, thumbnails, offline queues, web views, search indexes, notifications, and temporary exports. Preserve only records whose retention has an explicit product or legal basis, and do not imply that a local wipe can erase data already copied from a compromised device.

Treat platform features as bounded controls

Use the platform’s keystore, secure storage, cryptographic, authentication, and application-isolation facilities instead of inventing equivalents. Configure data protection, backup eligibility, file sharing, exported components, URL handlers, and inter-app communication deliberately. Platform defaults evolve, so release evidence should identify the actual configuration and supported OS range rather than rely on a remembered default.

A biometric prompt establishes local user presence to the platform’s degree of assurance. It does not identify the person to the server or authorize a reimbursement. Use it to unlock a local credential or require fresh local presence for a sensitive action, while the server still evaluates the account session, authorization, expense state, and risk. Define fallback behavior when biometrics change, the device passcode is removed, or the secure key becomes unavailable.

Permissions should correspond to current product behavior. Camera access for receipt capture does not justify full photo-library access; approximate location may be enough where precise location is unnecessary. Explain permission use at the moment the feature needs it, and remove permissions when the feature disappears. Review SDKs as part of this surface because an analytics, advertising, support, or crash-reporting SDK may receive the same device identifiers, screen content, network access, or lifecycle events as first-party code.

Data also escapes through surfaces that are not called storage: notification previews, screenshots and task switcher snapshots, clipboard contents, keyboard suggestions, logs, crash reports, analytics events, deep-link parameters, shared files, and embedded web content. For the approval notification, a generic locked-screen message may be safer than an employee name and amount. The authenticated app can retrieve details after it opens.

Carry one session across loss, replay, and recovery

Prefer a trusted system browser or platform-supported external authentication flow where appropriate, with redirect validation and protections against request substitution. Avoid collecting primary credentials inside an embedded view that the application fully controls. Whatever the sign-in interface, the resulting session needs an explicit lifecycle.

Mobile API session checklist

The session record should name:

  • the issuer, intended API audience, mobile client identity, redirect destinations, and proof that an authorization response belongs to the initiating request;
  • access- and refresh-token lifetimes, storage location, rotation and reuse behavior, and the boundary between local unlock and server authentication;
  • server authorization for each sensitive operation, including object scope, trusted fields, required recency or step-up authentication, and idempotency behavior;
  • revocation triggers for logout, password reset, account recovery, reported device loss, suspicious reuse, role removal, and administrative action;
  • what happens offline, after token expiry, during clock disagreement, and when a queued action is no longer legal at synchronization time;
  • privacy-safe events that reveal failed authentication, refresh-token reuse, unusual device change, repeated object denials, approval velocity, and recovery abuse.

Bind stronger sessions to proof held by the installation where the platform and threat justify it, but retain a recovery plan for device migration and key loss. Binding without recovery can turn a stolen-device defense into account lockout; recovery without equivalent scrutiny becomes the easier attack path.

Account recovery, MFA enrollment, push approval, QR pairing, support-assisted login, and addition of a new trusted device deserve the same review as sign-in. A push prompt should display enough transaction context to resist blind approval, expire promptly, and be bound to the server-side action it confirms. The server must not accept an approval merely because a device reported that a prompt was shown.

Assume the request can be rewritten

Use TLS for every API connection and the platform trust stack for certificate validation. Then test the API as though the client had already been patched. Change the expense id, organization id, amount, payee, workflow state, role, app version, device signal, and idempotency key. Remove UI fields, add hidden fields, replay requests, and call the endpoint without navigating through the app. The same object-authorization, schema, response-minimization, rate, and replay controls from the API playbook must survive.

Deep links and universal or application links are API inputs with an extra routing layer. Allow only intended schemes, hosts, paths, and parameters; reject ambiguous parsing; require authentication at the destination; and resolve authorization after navigation. A link may locate an expense. It must not carry a trusted statement that the expense is approved or belongs to the current user.

Old clients remain callers until the backend makes them harmless. Record supported API and app versions, compatibility promises, deprecation telemetry, minimum-version policy, and an emergency way to disable a dangerous flow. A forced upgrade has availability and incident consequences, so define who may invoke it and what the user can still do when the upgrade path is unavailable.

Pinning is an operating commitment

Certificate or public-key pinning can narrow which valid credentials the app accepts and can raise the cost of some interception. It can also strand clients when certificates, keys, intermediates, providers, CDNs, or inspection requirements change. Because a store update is neither instant nor universal, a bad pin can turn routine rotation into an outage that the server cannot repair.

Use pinning only when the threat reduction justifies that recovery burden. The design needs more than a current pin: backup trust material, overlap during rotation, expiry awareness, staged rollout, telemetry that distinguishes trust failure from ordinary network failure, an owner, and a tested emergency path. Do not weaken certificate validation globally to make a pinned configuration work, and do not describe pinning as protection from a compromised application process; code running under attacker control can often bypass the check.

Make client integrity useful without believing it

Obfuscation, symbol stripping, anti-tamper checks, debugger and emulator detection, root or jailbreak signals, and platform attestation can slow analysis and identify suspicious sessions. Apply them where extra attacker cost changes the economics of fraud, credential theft, automated scraping, or premium-feature abuse. Keep their operational purpose specific: which signal changes which risk decision, for how long, and with what appeal or recovery path?

These signals are probabilistic and bypassable. They can also be absent or misleading on legitimate devices, accessibility setups, beta OS versions, enterprise environments, and test infrastructure. Prefer proportionate responses: require fresh authentication, reduce transaction limits, withhold especially sensitive local data, challenge an action, or send it to review. A blanket device ban may be justified for a narrow high-risk product, but it should be an explicit availability and support decision rather than the foundation of API security.

The decisive test is simple: force every client-integrity signal to the favourable value, then send an unauthorized or impossible request. The server should still refuse another manager’s expense, a modified amount, an invalid state transition, and a replayed approval.

Release the application and the server as one security surface

Mobile release review must cover the signed client, store configuration, backend behavior, and versions still in use. For the expense approval, exercise the complete path on the oldest supported version as well as the candidate release. Inspect local files and backups, notification content, logs and crash reports, deep-link routing, session rotation and logout, modified API requests, and offline reconciliation. Test through an authorized interception environment when the transport design permits it; if pinning intentionally prevents that method, use an approved test build or instrumentation without weakening the production release.

Mobile security release checklist

A useful release record answers:

  1. Which data is stored, backed up, logged, placed on the clipboard, shown in notifications, or shared with SDKs, and what happens to each copy at logout or account removal?
  2. Which permissions, exported components, deep links, web views, SDKs, and platform capabilities changed?
  3. Which server tests prove object authorization, trusted-field use, legal state transitions, replay resistance, response minimization, and abuse limits when the client is modified?
  4. How were token issue, secure storage, refresh rotation, revocation, device loss, recovery, offline expiry, and migration exercised?
  5. If pinning or integrity signals are used, which failure telemetry, backup path, false-positive policy, rotation procedure, and emergency control were tested?
  6. Which signing identities and build inputs produced the release, who can publish it, which old versions remain active, and how can a dangerous operation be disabled without trusting the client?

The review is complete when it can distinguish three claims that are often collapsed: data on the device receives protection appropriate to its lifetime; the session can be contained when the device or credential is lost; and the server remains correct when the application lies. Only the last claim protects the reimbursement itself.