Skip to content
Cybersecurity9 min read

Mobile App Security Testing: What It Actually Covers, and Why It Isn't Web Testing With Extra Steps

Local storage, certificate pinning, binary hardening, MASVS — and the uncomfortable fact that most 'mobile' findings are really backend API bugs.

Published By the Safe Tech AI team

Decompile a typical Android APK and you will usually find, within the first hour, at least one API key, one hardcoded backend URL for a "staging" environment nobody decommissioned, and a shared-preferences file storing a session token in plain text. None of that requires a jailbreak, a rooted device, or dynamic instrumentation — just apktool and patience. The app was never attacked in the sense people imagine when they hear "penetration test." It was simply read.

That is the first thing to understand about mobile application security testing: the client binary sits in the attacker's hand, fully under their control, for as long as they want it. A web app's server-side logic is protected by the network boundary; a mobile app's client-side logic is not protected by anything except how carefully it was built. That single difference is why mobile application security testing is a distinct discipline rather than a web test performed on a smaller screen, and why treating it as an afterthought tends to be where the expensive findings live.

The device is not a trusted execution environment

Web security testing assumes the browser is hostile territory and puts the trust boundary at the server. Mobile testing has to go further, because the app itself — not just the network call it makes — is the thing under examination, and it persists on a device the user (or an attacker with physical access, a repackaged build, or malware on the same device) fully controls.

That reframes several things developers often get wrong by instinct:

  • Local storage is not private just because the OS sandboxes apps. Shared preferences on Android and NSUserDefaults/plist files on iOS are not encrypted by default. Backups, rooted or jailbroken devices, and malicious apps abusing accessibility services or content providers can all read data an app assumed was safe. Session tokens, refresh tokens, PII, and cached API responses are the recurring offenders — testing checks the keychain/Keystore is actually used for anything sensitive, rather than a database or a log file.
  • Logs are a data exfiltration channel. Verbose Log.d or NSLog calls left in production builds routinely contain tokens, PINs, or full request bodies, and on some Android versions other apps or ADB access can read them.
  • The backend does not get to assume the client is well-behaved. A request from "your" app and a request crafted in Burp Suite are indistinguishable to the server once someone has extracted the request format — which brings us to the point the rest of this article keeps returning to.

Definition — client-side control. Anything enforced only in the app (hidden UI elements, disabled buttons, client-side validation) is not a security control. It is a convenience for well-behaved users. The enforcement has to exist server-side or it does not exist.

Certificate pinning and transport security are necessary, not sufficient

TLS is table stakes; the more consequential mobile-specific question is whether the app pins the certificate or public key it expects, so a device with a user- or attacker-installed CA in its trust store still cannot MITM the connection. Without pinning, a proxy certificate installed during testing — or during an actual attack via a malicious profile — lets anyone intercept and modify traffic the app assumed was private.

Testing this properly means more than confirming pinning exists in code; it means confirming it is enforced consistently:

  • Pinning applied to the main API client but forgotten on a secondary SDK (analytics, crash reporting, an embedded WebView) that happens to carry sensitive query parameters or tokens.
  • Debug builds that disable pinning "temporarily" shipping to the store by mistake, because the flag was tied to a build variant nobody re-checked.
  • WebViews configured to ignore certificate errors, a pattern that turns up more often than it should in hybrid apps built on Cordova, Capacitor, or a bespoke bridge.
  • No pinning at all on a second or third-party API the app talks to directly — payment processors, analytics endpoints, or a partner's service — leaving a narrower but still real interception path.

Pinning failures degrade gracefully in the sense that TLS itself still blocks passive eavesdropping; what they remove is protection against an active, on-path adversary, which is exactly the scenario public Wi-Fi, compromised routers, and malicious VPN profiles create.

Reverse engineering and binary hardening

Every mobile binary ships to the attacker's device. Obfuscation, string encryption, root/jailbreak detection, and anti-tampering checks do not make reverse engineering impossible — nothing does, against a sufficiently motivated attacker with the binary in hand — but they raise the cost and close off the laziest attacks, which cover a surprising share of real abuse: casual API-key harvesting, quick UI-restriction bypasses, and copy-paste cloning of a competitor's client logic.

What a mobile assessment typically checks on the hardening side:

  • Whether string and constant obfuscation (ProGuard/R8 on Android, reasonable stripping on iOS) is actually enabled in the release build, not just configured and forgotten.
  • Whether root or jailbreak detection exists, and — more importantly — what the app does when it detects one. Detection that silently continues is decoration.
  • Whether sensitive logic (licensing checks, entitlement decisions, a discount calculation) runs client-side at all, since anything computed on the device can be patched or bypassed on the device.
  • Whether debug flags, verbose crash handlers, and test endpoints are compiled out of release builds rather than merely hidden behind a toggle.

None of this replaces server-side enforcement — it delays and discourages casual attackers rather than stopping a determined one — but for apps carrying real business logic risk (loyalty balances, entitlement flags, anti-cheat, DRM-adjacent features) it is a legitimate and frequently under-invested layer.

MASVS gives the assessment a shape, not a checklist to tick

The OWASP Mobile Application Security Verification Standard (MASVS) is the recognised reference framework for this domain, in the same way the OWASP Top 10 anchors web testing conversations. It organises requirements into groups covering architecture and data storage, cryptography, authentication and session management, network communication, platform interaction, code quality, and resilience against reverse engineering and tampering, with the companion Mobile Application Security Testing Guide (MASTG) supplying the concrete techniques testers use to verify each one on real iOS and Android builds.

The value of MASVS is less the list itself than the discipline of stating, before testing starts, which verification level applies — standard controls appropriate to most apps, or the additional resilience requirements that make sense for an app protecting high-value transactions or credentials. An app handling payments or health data justifies a different bar than an internal tool used by field staff on managed devices, and a credible mobile application security testing engagement scopes against that distinction explicitly rather than applying one generic checklist to every client regardless of what it actually does.

Most "mobile" vulnerabilities are backend vulnerabilities wearing a mobile costume

Here is the claim worth sitting with: intercept traffic from almost any mobile app using a proxy, and what you are testing from that point on is an API — the same broken object-level authorisation, the same missing function-level checks, the same over-permissive endpoints that show up in API security assessments generally. The mobile client is frequently just the delivery mechanism that got the tester a valid session token and a request format to replay outside the app entirely.

This matters commercially as much as technically. A team that commissions "a mobile pentest" expecting the finding list to be about the app itself is often surprised when the majority of serious issues are backend authorisation gaps — a user ID accepted from the client instead of derived from the token, an admin endpoint the app's UI never renders but the server never checks either. Those findings would exist even if the mobile client were deleted and replaced with curl scripts, because the vulnerability never lived in Swift or Kotlin — it lived in the request handler. A serious assessment therefore has to include API security testing against the backend the app talks to, not just static and dynamic analysis of the client binary; testing only the app and waving the API through because "it's internal" or "it's not directly reachable" leaves the part that usually matters most unexamined.

Where mobile testing genuinely diverges from web testing

It is worth being precise about what actually changes, because the overlap with web application security testing is larger than marketing material from either side tends to admit. The shared ground — authentication logic, session handling, the API surface, authorisation between users and roles — is tested the same way regardless of which client calls it. What is genuinely mobile-specific is everything that depends on the device as a physical, persistent artifact: on-disk storage a user could extract via backup or a rooted device, IPC exposure between apps on the same phone, pinning and its failure modes, and the binary itself being available for static analysis in a way a web app's server code never is. Testing that ignores the client-side half misses device-resident risk; testing that ignores the backend half misses most of the actual exploitable severity. Neither half is optional.

Where this lands

A mobile assessment worth paying for looks at four things together: what the app stores on the device and how, whether transport is genuinely protected against an active attacker rather than merely encrypted, whether the binary makes casual reverse engineering meaningfully harder, and — carrying most of the real risk — whether the backend API enforces authorisation correctly regardless of which client is calling it. If you are scoping a mobile release that handles payments, health data, or credentials, or you inherited an app from a previous vendor and have never had the client-server pair examined together, that's a conversation worth having before the next release ships.

Topics:mobile securityowasp masvsapi securitypenetration testing

Related reading

Dealing with this in your own systems?

Tell us where you're stuck and we'll tell you plainly whether it's something to fix yourselves or worth bringing us in for.

Talk to our team