Mobile applications handle some of the most sensitive data in the enterprise: health records, financial credentials, location history, corporate email, and authentication tokens. Yet mobile security testing is frequently deprioritized or treated as an afterthought in development cycles. The consequences are predictable: cleartext credentials in log files, broken certificate pinning that makes HTTPS traffic readable on any local network, authentication tokens stored in insecure locations accessible to any application on the device, and local authentication bypasses that defeat biometric controls without requiring the user's fingerprint or face.
This post covers a practitioner's approach to mobile application security testing for both iOS and Android, grounded in the OWASP Mobile Application Security Verification Standard (MASVS).
OWASP MASVS: The Testing Framework
The OWASP MASVS (current version: MASVS 2.0) organizes mobile security requirements into six categories:
- MASVS-STORAGE: Sensitive data at rest — keychain/keystore usage, file permissions, backup exclusion
- MASVS-CRYPTO: Cryptographic implementation — algorithm selection, key management, random number generation
- MASVS-AUTH: Authentication and session management — local authentication, biometrics, session token handling
- MASVS-NETWORK: Network communication security — TLS configuration, certificate pinning, cleartext traffic
- MASVS-PLATFORM: Platform interaction security — intent handling, IPC mechanisms, WebView configuration
- MASVS-CODE: Code quality and resilience — anti-tampering, obfuscation, root/jailbreak detection
Android-Specific Testing
Exported Activities and Intent Injection
Android components (Activities, Services, BroadcastReceivers, ContentProviders) can be exported — accessible to other applications on the device. An exported activity that performs a sensitive action (password reset, deep link handling, payment initiation) without validating the calling application's identity is exploitable. Review AndroidManifest.xml for components with android:exported="true" that lack proper permission checks. Test by using ADB to launch exported activities directly: adb shell am start -n com.example.app/.InternalActivity.
Intent injection occurs when an application constructs implicit intents with attacker-controlled data (e.g., processing a deep link URL and passing it as an intent extras), potentially redirecting the intent to a malicious application that intercepts the data.
Insecure Data Storage
SharedPreferences is frequently misused for sensitive data storage. SharedPreferences files are world-readable on rooted devices and backed up via ADB by default (unless android:allowBackup="false" is set). Pull and inspect: adb backup -noapk com.example.app && dd if=backup.ab bs=24 skip=1 | python3 -c "import zlib,sys; sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))" | tar xf -. Check shared_prefs/ for tokens, user data, and configuration.
SQLite databases stored in the application's data directory are another common finding location. Use ADB shell to browse /data/data/com.example.app/databases/ on a rooted device and inspect with sqlite3.
Tapjacking
Tapjacking (clickjacking for Android) overlays a transparent malicious view over a sensitive application screen, capturing touch events intended for the legitimate application. Mitigate with android:filterTouchesWhenObscured="true" on sensitive UI elements.
iOS-Specific Testing
Keychain Storage
The iOS Keychain is the correct storage location for credentials and sensitive tokens. Items stored with the accessibility level kSecAttrAccessibleAlways or kSecAttrAccessibleAlwaysThisDeviceOnly are accessible even when the device is locked — an unnecessary exposure. Items should use kSecAttrAccessibleWhenUnlockedThisDeviceOnly for credentials that do not need background access. Use keychain-dumper on a jailbroken device to enumerate all keychain items accessible to the application.
URL Scheme Hijacking
iOS custom URL schemes (e.g., myapp://reset-password?token=abc123) can be registered by any application. If two applications register the same scheme, iOS may route the deep link to the malicious application, potentially capturing OAuth tokens or password reset links embedded in URL scheme callbacks. Universal Links (HTTPS-based, requiring server-side association file validation) mitigate this but are frequently not implemented.
Clipboard Sniffing and Snapshot Leakage
iOS allows any application to read the system clipboard, enabling credential theft from password managers via clipboard. Test: copy a password into the target application's password field, then read the clipboard from another application. Snapshots: iOS automatically captures application screenshots for the app switcher, potentially including sensitive screens. Implement applicationWillResignActive or SceneDelegate lifecycle methods to blank sensitive screens before snapshotting.
Dynamic Analysis: Frida and SSL Unpinning
Dynamic analysis instruments the running application. Frida is the primary tool: a dynamic instrumentation framework that injects JavaScript into the application process to hook, intercept, and modify function calls at runtime.
SSL/TLS certificate pinning prevents traffic interception by validating the server certificate against an embedded pin. Bypassing pinning to intercept traffic with Burp Suite is a standard first step in mobile testing. Common Frida scripts for unpinning:
objection(wraps Frida):objection --gadget com.example.app explorethenios sslpinning disableorandroid sslpinning disable- Frida CodeShare scripts for specific pinning implementations (TrustKit, OkHttp CertificatePinner, NSURLSession)
- Manual Frida hooks targeting
SecTrustEvaluate(iOS) orcheckServerTrusted(Android)
Static Analysis
Static analysis extracts and inspects application code without running it:
- Android:
apktool d app.apkdecompiles resources and smali bytecode.jadx -d output/ app.apkproduces readable Java source. Review for hardcoded secrets, API keys, cryptographic key material, and insecure configuration. - iOS: Decrypt the IPA from a jailbroken device using frida-ios-dump.
class-dumpextracts Objective-C class headers from the Mach-O binary. Strings analysis:stringscommand orgrepacross the binary for API keys, URLs, and credentials. - MobSF (Mobile Security Framework): Automated static and dynamic analysis platform. Upload APK or IPA for automated extraction of permissions, exported components, hardcoded secrets, and security control weaknesses. Available as open source at github.com/MobSF/Mobile-Security-Framework-MobSF.
Common High-Severity Findings
Across mobile application security testing aligned to OWASP MASVS, the most commonly identified high-severity findings are:
- Cleartext credentials in log files: Applications logging authentication tokens or user credentials to Logcat (Android) or NSLog (iOS). On production builds, logging of sensitive data must be stripped.
- Broken certificate pinning: Pinning implemented in one code path but bypassed via alternate network libraries or WebView traffic.
- Local authentication bypass: Biometric authentication implemented as a client-side gate that does not cryptographically bind to a server-side secret — bypass by manipulating the local authentication result via Frida.
- Insecure OAuth token storage: Access tokens stored in localStorage (React Native WebView), AsyncStorage without encryption, or SharedPreferences.
Fortress MSSP conducts iOS and Android security assessments aligned to OWASP MASVS for enterprise mobile applications. Contact us to discuss a mobile application security assessment for your application portfolio.