Mobile App Penetration Testing: What Actually Gets Tested
Mobile app penetration testing is web testing plus a second attack surface: the device itself. Data that would sit on a server in a web app lives in the app's local storage, and the app's trust decisions can be reversed or bypassed entirely. This post covers what a mobile assessment actually tests, from the device up.
The mobile attack surface is bigger than the app
The app is the smallest part of the engagement. Around it sit the device filesystem and OS, the network path to the API, the API itself, third-party SDKs, deep links, backup behavior, and the store distribution process. A thorough test covers all of it, and the API is usually where the real vulnerabilities live.
The reference points are the OWASP Mobile Application Security Verification Standard (MASVS) and the Mobile Application Security Testing Guide (MASTG). MASVS defines verification levels so you can specify how deep the testing goes; MASTG defines the test procedures.
Setting up the test environment
Testing starts with an intercepting proxy, a rooted device or emulator, and the ability to see the app's traffic. Certificate pinning is the first hurdle: tools like Frida and objection hook the app's TLS verification at runtime to bypass pinning. This is standard practice, and it is a finding in itself when bypassing takes seconds.
Use a mix of emulators and real devices. Emulators miss device-specific behavior: hardware-backed keystores, biometric flows, and vendor modifications. At least one real device per platform belongs in every engagement.
Test on both platforms if the app ships for Android and iOS, and include the lowest OS version the app still supports. Older protection mechanisms are more likely to be present there, and users run old versions for years.
Client-side testing
- Storage: on Android, check SharedPreferences, SQLite databases, logs, and caches for secrets in cleartext (CWE-312). On iOS, verify what is in the Keychain versus unprotected app data. Hardcoded API keys and tokens in the binary are still common (CWE-798).
- Exported components: Android activities, services, and content providers that should not be exported can be invoked by other apps (CWE-926). Intent injection reaches internal functionality the UI never exposes.
- Root and jailbreak detection: if it exists, the question is whether it holds up. Detection that a tester bypasses in minutes is cosmetic, not a control.
- Binary analysis: strings and lightweight disassembly surface secrets, debug flags, and logic that should not ship.
- Logging and error paths: debug builds that log tokens or stack traces, and release builds that kept the same behavior. Also check clipboard handling and screen capture protection anywhere sensitive data is displayed.
- IPC and platform entry points: exported services, broadcast receivers, and content providers on Android; URL schemes and universal links on iOS. Each is a way to invoke app functionality without the UI.
Network and API testing
Once traffic is interceptable, mobile API testing is API penetration testing: authentication and session handling, object-level authorization, injection, and rate limiting. The API is where user data crosses trust boundaries, so this is where impact concentrates. Our API penetration testing checklist covers the API-specific pass.
Also check transport behavior: whether the app allows cleartext traffic, whether TLS validation can be disabled, and how WebViews are configured. Pinning that is baked in and enforced matters; a setting that says "no pinning in debug" only needs one misconfigured build to vanish.
WebViews deserve their own pass. An app that loads remote content into a WebView with JavaScript enabled and addJavascriptInterface exposed on Android hands a scriptable bridge to anyone who controls that content. Check which domains WebViews trust, whether navigation is restricted, and whether file access is enabled.
What most tests miss
- Backup leakage. Android backups and iOS device backups can include app data (CWE-921). A token that survives an app reinstall through a backup is effectively a persistent credential.
- Deep links and intent schemes. Reachable routes into the app's UI and logic that never appear in the interface.
- Third-party SDKs. Analytics, crash reporting, and chat SDKs ship their own permissions, endpoints, and storage. They expand the attack surface beyond what the app team wrote.
- The store artifact. The signed package itself: version history, sideloading behavior, and what the distribution channel exposes.
- Update and rollback behavior. Whether a downgraded version of the app re-enables protections added in later releases.
[ILLUSTRATIVE] As an example of the backup class: an app storing a refresh token in plaintext app storage that survived reinstall via Android backup, keeping the session alive on a fresh device. Replace with a verified finding before publishing.
Takeaways
- Test the API, not just the app. That is where the impact lives.
- Rooted-device testing with Frida is standard; detection that is trivially bypassed is not a control.
- Check storage, backups, exported components, deep links, and third-party SDKs.
- Use OWASP MASVS levels to define and communicate exactly how deep the test goes.
NIMR's mobile and network security testing covers Android and iOS with manual testing on real devices, on top of the API work in our web & API VAPT. Request an assessment to scope your app.