Mobile App Security Testing: A Practical Guide for 2025
On this page
Why Mobile App Security Matters More Than Ever
Mobile apps handle sensitive data — banking, healthcare, authentication, personal communications. Yet 80% of mobile apps we audit have at least one critical vulnerability.
The OWASP Mobile Top 10 (2024) lists the most critical mobile security risks:
| # | Risk | Prevalence |
|---|---|---|
| M1 | Improper Credential Usage | Very Common |
| M2 | Inadequate Supply Chain Security | Common |
| M3 | Insecure Authentication/Authorization | Very Common |
| M4 | Insufficient Input/Output Validation | Common |
| M5 | Insecure Communication | Common |
| M6 | Inadequate Privacy Controls | Common |
| M7 | Insufficient Binary Protections | Very Common |
| M8 | Security Misconfiguration | Very Common |
| M9 | Insecure Data Storage | Very Common |
| M10 | Insufficient Cryptography | Common |
Testing Area #1: Insecure Data Storage
Mobile apps frequently store sensitive data in insecure locations.
What to Check (Android)
# Check SharedPreferences for sensitive data
adb shell cat /data/data/com.example.app/shared_prefs/*.xml
# Check SQLite databases
adb shell sqlite3 /data/data/com.example.app/databases/app.db ".dump"
# Check for sensitive data in logs
adb logcat | grep -i "password\|token\|api_key\|secret"
# Check external storage (world-readable!)
adb shell ls /sdcard/Android/data/com.example.app/
What to Check (iOS)
# Check Keychain (using objection)
objection -g com.example.app explore
> ios keychain dump
# Check NSUserDefaults (plist files)
> ios plist cat NSUserDefaults
# Check for sensitive data in Core Data / SQLite
> sqlite connect Library/Application\ Support/app.sqlite
❌ Vulnerable (Android — Storing token in SharedPreferences)
// INSECURE — SharedPreferences is stored in plain XML
val prefs = getSharedPreferences("auth", MODE_PRIVATE)
prefs.edit().putString("access_token", token).apply()
prefs.edit().putString("refresh_token", refreshToken).apply()
✅ Fixed (Android — Using EncryptedSharedPreferences)
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val securePrefs = EncryptedSharedPreferences.create(
context,
"secure_auth",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
securePrefs.edit().putString("access_token", token).apply()
Testing Area #2: Certificate Pinning Bypass
If your app doesn't pin certificates, attackers on the same network can intercept HTTPS traffic.
Test with Frida
// frida-ssl-pin-bypass.js
Java.perform(function () {
var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
// This script bypasses certificate pinning
// If it works, your app is vulnerable
var TrustAllManager = Java.registerClass({
name: 'com.frida.TrustAllManager',
implements: [TrustManager],
methods: {
checkClientTrusted: function (chain, authType) {},
checkServerTrusted: function (chain, authType) {},
getAcceptedIssuers: function () { return []; },
},
});
});
✅ Fix: Implement Certificate Pinning
// Android — OkHttp Certificate Pinning
val client = OkHttpClient.Builder()
.certificatePinner(
CertificatePinner.Builder()
.add("api.example.com",
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") // Primary
.add("api.example.com",
"sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=") // Backup
.build()
)
.build()
Testing Area #3: Reverse Engineering & Hardcoded Secrets
Android APK Analysis
# Decompile APK
apktool d app.apk -o app_decompiled
# Search for hardcoded secrets
grep -r "api_key\|secret\|password\|token" app_decompiled/
grep -r "https://\|http://" app_decompiled/smali/
# Use jadx for Java source
jadx -d output app.apk
grep -r "API_KEY\|SECRET" output/
iOS IPA Analysis
# Extract IPA
unzip app.ipa -d app_extracted
# Check for hardcoded strings
strings app_extracted/Payload/App.app/App | grep -i "key\|secret\|password"
# Check Info.plist for sensitive configs
plutil -p app_extracted/Payload/App.app/Info.plist
Testing Area #4: Insecure API Communication
# Intercept traffic with mitmproxy
mitmproxy --mode transparent --listen-port 8080
# Check for:
# - Sensitive data sent over HTTP (not HTTPS)
# - Tokens in URL query parameters (logged by proxies)
# - Missing authentication on sensitive endpoints
# - Excessive data in API responses
Testing Area #5: Authentication Flaws
Common Mobile Auth Vulnerabilities
- Biometric bypass — Fallback to weak PIN
- Token stored insecurely — Plain text in SharedPreferences
- No session expiration — Tokens valid for months
- Missing re-authentication — Sensitive actions without password confirmation
- Client-side auth checks — Easily bypassed with Frida
// Frida — Bypass client-side auth check
Java.perform(function () {
var AuthManager = Java.use('com.example.app.AuthManager');
AuthManager.isAuthenticated.implementation = function () {
console.log('Bypassed isAuthenticated');
return true; // Always return authenticated
};
});
Free Tools for Mobile Security Testing
| Tool | Platform | Purpose |
|---|---|---|
| MobSF | Both | Automated static/dynamic analysis |
| Frida | Both | Runtime instrumentation |
| Objection | Both | Runtime exploration |
| Jadx | Android | APK decompilation |
| apktool | Android | APK resource extraction |
| Hopper | iOS | Binary analysis |
| mitmproxy | Both | Traffic interception |
| Drozer | Android | IPC / exported component testing |
Mobile Security Testing Checklist
| # | Test | Priority |
|---|---|---|
| 1 | Check for insecure data storage | Critical |
| 2 | Test certificate pinning | High |
| 3 | Search for hardcoded secrets | Critical |
| 4 | Intercept API traffic | High |
| 5 | Test authentication bypass | Critical |
| 6 | Check binary protections (obfuscation) | Medium |
| 7 | Test exported components (Android) | High |
| 8 | Check for debug/logging in release builds | Medium |
| 9 | Verify clipboard data handling | Medium |
| 10 | Test deep link/URL scheme handling | High |
Need a Mobile App Security Audit?
We do hands-on security testing for Android and iOS applications. Request a free consultation →
Published by the SecureCodeReviews.com team — mobile application security specialists.
Published by SecureCodeReviews
This article is part of our original AI security and cybersecurity content library. We show publish and update dates, keep company and policy pages public, and update important guidance when material changes affect readers.
Want an expert review before this issue reaches production?
We combine manual code review with AppSec tooling to find vulnerabilities, logic flaws, and insecure patterns before release or audit deadlines.
Advertisement