Mobile Audit — iOS & Android Application Security Review
Audit mobile apps against the OWASP Mobile Application Security Verification Standard (MASVS) and Mobile Application Security Testing Guide (MASTG). Covers source code review, static analysis of compiled binaries, and runtime testing.
Scope: this skill covers the app and its interaction with the device, the backend, and other apps. For backend API security, pair with api-audit. For dependency CVEs (CocoaPods, SPM, Gradle), pair with dependency-audit.
Authorization Check
Before reverse-engineering or runtime-testing a binary, confirm:
- The app is yours, or you have written authorization from the publisher
- You're operating in an environment you control (test device, emulator, dedicated sandbox)
- App store ToS — Apple and Google generally allow security research on apps you own; testing competitor apps without authorization is a fast path to legal exposure
If unclear, ask before proceeding.
Audit Checklist — MASVS-STORAGE (Sensitive Data Storage)
- iOS: keychain items use the strongest available
kSecAttrAccessible class — kSecAttrAccessibleWhenUnlockedThisDeviceOnly or kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly. Avoid Always and ThisDeviceOnly-less variants
- iOS: no secrets in
NSUserDefaults, plist, or app bundle — strings <app>.ipa should not reveal API keys or secrets
- Android: secrets in EncryptedSharedPreferences / Keystore-backed encrypted storage, not raw SharedPreferences
- Android:
android:allowBackup="false" in the manifest (or backup rules carefully scoped) — otherwise adb backup extracts everything
- Both: no PII / tokens written to logs that survive a crash (NSLog, Log.d, third-party crash reporters)
- Both: Pasteboard / Clipboard access — sensitive fields don't auto-share to system clipboard (iOS
pasteboard.expirationDate, Android ClipDescription.EXTRA_IS_SENSITIVE)
- Both: the OS app-switcher screenshot doesn't capture sensitive screens — iOS
applicationDidEnterBackground blur, Android FLAG_SECURE on the activity
Audit Checklist — MASVS-CRYPTO (Cryptography)
- No hardcoded keys in the app bundle —
strings, class-dump, apktool reveal embedded constants
- Modern algorithms only — AES-GCM, ChaCha20-Poly1305; reject AES-ECB, DES, RC4, MD5, SHA-1
- Random number generation uses
SecRandomCopyBytes (iOS) / SecureRandom (Android) — not arc4random() for crypto, never Math.random()
- Key derivation from passwords uses PBKDF2 with ≥ 600,000 iterations (OWASP 2024) or Argon2id
- IVs / nonces are not reused — if you see
iv = "0000000000000000", that's worse than no encryption (reveals plaintext patterns)
- Don't roll your own crypto — flag any custom encryption scheme; bias toward libsodium / Tink
Audit Checklist — MASVS-NETWORK (Network Communication)
- iOS: App Transport Security enabled — no global
NSAllowsArbitraryLoads = true. If exceptions exist, they're specific domains, justified, and documented
- Android:
network_security_config.xml exists and enforces cleartext-traffic refusal — <base-config cleartextTrafficPermitted="false">
- Both: Certificate pinning for high-trust backends — public-key pinning preferred over certificate pinning (survives cert rotation). For iOS:
URLSessionDelegate + URLAuthenticationChallenge; Android: NetworkSecurityConfig <pin-set> or OkHttp CertificatePinner
- Both: Pinning has a backup pin — pinning to a single cert means the next rotation breaks the app for all users
- WebView usage —
WKWebView only (iOS, not UIWebView); JavaScript bridge audited; setJavaScriptEnabled(false) if the WebView doesn't need JS
- WebView
loadUrl with user-controlled URL — open redirect, intent-spoofing, phishing surface
Audit Checklist — MASVS-AUTH (Authentication & Session)
- Biometric prompts use
LAContext.evaluatePolicy (iOS) / BiometricPrompt (Android) — not the deprecated FingerprintManager
- Biometric auth is bound to keychain/keystore access, not just a UI check (
SecAccessControl.biometryAny, Android KeyGenParameterSpec.setUserAuthenticationRequired(true))
- Session tokens stored in keychain/keystore (not SharedPreferences/NSUserDefaults)
- Refresh-token flow — short-lived access token, refresh token revocable server-side
- OAuth flows use the platform browser (ASWebAuthenticationSession on iOS, Custom Tabs on Android) — never a WebView (steals credentials trivially)
- App-level passcode independent of device unlock if the app holds sensitive data
Audit Checklist — MASVS-PLATFORM (Platform Interaction)
Deeplinks / URL schemes (iOS) and Intent filters (Android)
- Every exported activity (
android:exported="true") reviewed for parameter handling
- Universal Links (iOS) and App Links (Android) use HTTPS + verified domain — not custom schemes (
myapp://) which any app can register
- Deeplinks that trigger sensitive actions (purchase, share, change account) require user confirmation in-app
- WebView-loaded URLs filtered — opening
myapp:// from a WebView to trigger an in-app action without user consent is an XSS-to-action chain
Inter-process communication (Android)
- Content providers —
android:exported="false" unless explicitly intended for cross-app access; if exported, every URI path validated
- Services — exported services have permission strings; exposed without
android:permission is callable by any app
- Broadcast receivers —
LocalBroadcastManager for in-app broadcasts; system broadcasts validated
Inter-process communication (iOS)
- App groups configured only when sharing is genuinely required
- Keychain access groups limited to your own apps (no shared keychain group with unrelated bundles)
- URL scheme handlers validate the source app (
UIApplication.openURL options include UIApplicationOpenURLOptionsSourceApplicationKey)
Audit Checklist — MASVS-CODE (Code Quality)
- Native libraries — modern compilers, no stack canaries disabled, PIE enabled (
otool -hv on iOS, readelf -h on Android .so)
- Symbols stripped from release builds (
strip, ProGuard/R8)
- No debug builds in production (
DEBUG flag, isDebuggable in manifest)
- No reflection-based hidden APIs (Android non-SDK interfaces) — break on OS upgrades
- Updates: in-app update prompt that forces upgrade past known-vulnerable versions
Audit Checklist — MASVS-RESILIENCE (Anti-Reverse-Engineering)
This category is rated optional in MASVS — only required for high-risk apps (banking, DRM, government). For most apps, don't waste effort here; ship secure crypto and a proper backend.
If required:
- Jailbreak / root detection — not bulletproof (every detection technique has a public bypass) but raises the cost
- Code obfuscation — DexGuard / Arxan for high-value apps; standard ProGuard / R8 minimally for everyone
- Anti-debugging —
ptrace self-attach (iOS / Linux), Debug.isDebuggerConnected (Android)
- SSL pinning resistant to Frida-style bypass — pin in native code, not Swift / Kotlin
Note: every resilience control will be bypassed by a determined attacker with physical device access. They buy time, they don't prevent.
Static analysis tools
| Tool |
Platform |
Use |
| MobSF |
iOS + Android |
Automated static + dynamic scanner; first-pass triage |
| nuclei + mobile templates |
Both |
Pattern-based scanner |
| semgrep + mobile rules |
Both |
AST-based rules |
| jadx |
Android |
Decompile APK to Java |
| apktool |
Android |
Disassemble APK |
| Hopper / Ghidra / IDA |
iOS |
Disassemble Mach-O |
| class-dump / nm / otool |
iOS |
Symbol and structure inspection |
strings |
Both |
First check — secrets, URLs, debug strings |
| Frida + objection |
Both |
Runtime instrumentation, SSL-pinning bypass, method tracing |
Runtime testing
For grey/black-box assessment, use a non-personal device:
- Burp Suite / mitmproxy as system proxy on the test device — observe API traffic
- Bypass SSL pinning with Frida +
objection if you need to see encrypted traffic during testing
- Modify requests, replay them, look for IDOR / BFLA (see
api-audit)
- Force background → resume to test session handling and screenshot blur
- Force-quit → relaunch to test session persistence and auto-login
- Install a malicious sibling app and test IPC paths (Android Intent fuzzing)
Output Format
# Mobile Application Security Audit
## App: [name + version]
## Platform: iOS / Android / both
## MASVS profile: L1 / L2 / R (resilience required)
## Date: [date]
### Executive summary
[2-3 paragraphs]
### MASVS category findings
| Category | Findings | Severity high-water mark |
|---|---|---|
| STORAGE | N | |
| CRYPTO | N | |
| NETWORK | N | |
| AUTH | N | |
| PLATFORM | N | |
| CODE | N | |
| RESILIENCE | N | (only if R-profile) |
### Per-finding detail
[Title, MASVS-ID, severity, description, location, evidence, remediation, verification]
### Backend API findings
[Cross-link to api-audit / owasp-audit output]
### Recommendations
[Prioritized 30/60/90 day fixes]
Boundaries
- Audit only apps you own or have written authorization to test
- Reverse-engineering a competitor's app is a legal risk — refuse unless the user can show authorization
- Frida / Objection / SSL-pinning bypass are for your own apps in test environments — they are not "test in production" tools
- Refuse to help build malware, surveillance apps, or stalkerware
- If the audit surfaces evidence of an active backdoor in someone else's code, escalate; don't quietly fix and forget
References
- OWASP MASVS (Mobile Application Security Verification Standard)
- OWASP MASTG (Mobile Application Security Testing Guide)
- OWASP Mobile Top 10
- Apple Security: Apple Platform Security Guide
- Android Security: Android Security Best Practices
- iOS App Programming Guide — Security
- "iOS Application Security" — David Thiel
- "Android Hacker's Handbook"
1---
2name: mobile-audit
3description: "Audit iOS and Android mobile applications against OWASP MASVS / MASTG — insecure storage, weak crypto, certificate pinning, deeplinks, IPC, jailbreak/root detection, reverse-engineering resistance. Use when the user mentions 'mobile security,' 'iOS security,' 'Android security,' 'mobile audit,' 'mobile pentest,' 'MASVS,' 'MASTG,' 'certificate pinning,' 'jailbreak detection,' 'root detection,' 'deeplink,' 'URL scheme,' 'app transport security,' 'keychain,' 'keystore,' 'mobile reverse engineering,' or has a mobile app to review."
4allowed-tools: Bash, Read, Write, Grep, Glob, WebSearch
5---
6
7# Mobile Audit — iOS & Android Application Security Review
8
9Audit mobile apps against the OWASP Mobile Application Security Verification Standard (MASVS) and Mobile Application Security Testing Guide (MASTG). Covers source code review, static analysis of compiled binaries, and runtime testing.
10
11Scope: this skill covers the *app* and its interaction with the device, the backend, and other apps. For backend API security, pair with `api-audit`. For dependency CVEs (CocoaPods, SPM, Gradle), pair with `dependency-audit`.
12
13## Authorization Check
14
15Before reverse-engineering or runtime-testing a binary, confirm:
161. The app is yours, or you have written authorization from the publisher
172. You're operating in an environment you control (test device, emulator, dedicated sandbox)
183. App store ToS — Apple and Google generally allow security research on apps you own; testing competitor apps without authorization is a fast path to legal exposure
19
20If unclear, ask before proceeding.
21
22## Audit Checklist — MASVS-STORAGE (Sensitive Data Storage)
23
24- **iOS:** keychain items use the strongest available `kSecAttrAccessible` class — `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` or `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`. Avoid `Always` and `ThisDeviceOnly`-less variants
25- **iOS:** no secrets in `NSUserDefaults`, plist, or app bundle — `strings <app>.ipa` should not reveal API keys or secrets
26- **Android:** secrets in EncryptedSharedPreferences / Keystore-backed encrypted storage, not raw SharedPreferences
27- **Android:** `android:allowBackup="false"` in the manifest (or backup rules carefully scoped) — otherwise `adb backup` extracts everything
28- **Both:** no PII / tokens written to logs that survive a crash (NSLog, Log.d, third-party crash reporters)
29- **Both:** Pasteboard / Clipboard access — sensitive fields don't auto-share to system clipboard (iOS `pasteboard.expirationDate`, Android `ClipDescription.EXTRA_IS_SENSITIVE`)
30- **Both:** the OS app-switcher screenshot doesn't capture sensitive screens — iOS `applicationDidEnterBackground` blur, Android `FLAG_SECURE` on the activity
31
32## Audit Checklist — MASVS-CRYPTO (Cryptography)
33
34- No hardcoded keys in the app bundle — `strings`, `class-dump`, `apktool` reveal embedded constants
35- Modern algorithms only — AES-GCM, ChaCha20-Poly1305; reject AES-ECB, DES, RC4, MD5, SHA-1
36- Random number generation uses `SecRandomCopyBytes` (iOS) / `SecureRandom` (Android) — not `arc4random()` for crypto, never `Math.random()`
37- Key derivation from passwords uses PBKDF2 with ≥ 600,000 iterations (OWASP 2024) or Argon2id
38- IVs / nonces are not reused — if you see `iv = "0000000000000000"`, that's worse than no encryption (reveals plaintext patterns)
39- Don't roll your own crypto — flag any custom encryption scheme; bias toward libsodium / Tink
40
41## Audit Checklist — MASVS-NETWORK (Network Communication)
42
43- **iOS:** App Transport Security enabled — no global `NSAllowsArbitraryLoads = true`. If exceptions exist, they're specific domains, justified, and documented
44- **Android:** `network_security_config.xml` exists and enforces cleartext-traffic refusal — `<base-config cleartextTrafficPermitted="false">`
45- **Both:** Certificate pinning for high-trust backends — public-key pinning preferred over certificate pinning (survives cert rotation). For iOS: `URLSessionDelegate` + `URLAuthenticationChallenge`; Android: `NetworkSecurityConfig` `<pin-set>` or OkHttp `CertificatePinner`
46- **Both:** Pinning has a backup pin — pinning to a single cert means the next rotation breaks the app for all users
47- WebView usage — `WKWebView` only (iOS, not `UIWebView`); JavaScript bridge audited; `setJavaScriptEnabled(false)` if the WebView doesn't need JS
48- WebView `loadUrl` with user-controlled URL — open redirect, intent-spoofing, phishing surface
49
50## Audit Checklist — MASVS-AUTH (Authentication & Session)
51
52- Biometric prompts use `LAContext.evaluatePolicy` (iOS) / `BiometricPrompt` (Android) — not the deprecated `FingerprintManager`
53- Biometric auth is bound to keychain/keystore access, not just a UI check (`SecAccessControl.biometryAny`, Android `KeyGenParameterSpec.setUserAuthenticationRequired(true)`)
54- Session tokens stored in keychain/keystore (not SharedPreferences/NSUserDefaults)
55- Refresh-token flow — short-lived access token, refresh token revocable server-side
56- OAuth flows use the platform browser (ASWebAuthenticationSession on iOS, Custom Tabs on Android) — never a WebView (steals credentials trivially)
57- App-level passcode independent of device unlock if the app holds sensitive data
58
59## Audit Checklist — MASVS-PLATFORM (Platform Interaction)
60
61### Deeplinks / URL schemes (iOS) and Intent filters (Android)
62
63- Every exported activity (`android:exported="true"`) reviewed for parameter handling
64- Universal Links (iOS) and App Links (Android) use HTTPS + verified domain — not custom schemes (`myapp://`) which any app can register
65- Deeplinks that trigger sensitive actions (purchase, share, change account) require user confirmation in-app
66- WebView-loaded URLs filtered — opening `myapp://` from a WebView to trigger an in-app action without user consent is an XSS-to-action chain
67
68### Inter-process communication (Android)
69
70- Content providers — `android:exported="false"` unless explicitly intended for cross-app access; if exported, every URI path validated
71- Services — exported services have permission strings; exposed without `android:permission` is callable by any app
72- Broadcast receivers — `LocalBroadcastManager` for in-app broadcasts; system broadcasts validated
73
74### Inter-process communication (iOS)
75
76- App groups configured only when sharing is genuinely required
77- Keychain access groups limited to your own apps (no shared keychain group with unrelated bundles)
78- URL scheme handlers validate the source app (`UIApplication.openURL` options include `UIApplicationOpenURLOptionsSourceApplicationKey`)
79
80## Audit Checklist — MASVS-CODE (Code Quality)
81
82- Native libraries — modern compilers, no stack canaries disabled, PIE enabled (`otool -hv` on iOS, `readelf -h` on Android `.so`)
83- Symbols stripped from release builds (`strip`, ProGuard/R8)
84- No debug builds in production (`DEBUG` flag, `isDebuggable` in manifest)
85- No reflection-based hidden APIs (Android non-SDK interfaces) — break on OS upgrades
86- Updates: in-app update prompt that forces upgrade past known-vulnerable versions
87
88## Audit Checklist — MASVS-RESILIENCE (Anti-Reverse-Engineering)
89
90This category is rated optional in MASVS — only required for high-risk apps (banking, DRM, government). For most apps, **don't waste effort here**; ship secure crypto and a proper backend.
91
92If required:
93- Jailbreak / root detection — not bulletproof (every detection technique has a public bypass) but raises the cost
94- Code obfuscation — DexGuard / Arxan for high-value apps; standard ProGuard / R8 minimally for everyone
95- Anti-debugging — `ptrace` self-attach (iOS / Linux), `Debug.isDebuggerConnected` (Android)
96- SSL pinning resistant to Frida-style bypass — pin in native code, not Swift / Kotlin
97
98Note: every resilience control will be bypassed by a determined attacker with physical device access. They buy time, they don't prevent.
99
100## Static analysis tools
101
102| Tool | Platform | Use |
103|---|---|---|
104| MobSF | iOS + Android | Automated static + dynamic scanner; first-pass triage |
105| nuclei + mobile templates | Both | Pattern-based scanner |
106| semgrep + mobile rules | Both | AST-based rules |
107| jadx | Android | Decompile APK to Java |
108| apktool | Android | Disassemble APK |
109| Hopper / Ghidra / IDA | iOS | Disassemble Mach-O |
110| class-dump / nm / otool | iOS | Symbol and structure inspection |
111| `strings` | Both | First check — secrets, URLs, debug strings |
112| Frida + objection | Both | Runtime instrumentation, SSL-pinning bypass, method tracing |
113
114## Runtime testing
115
116For grey/black-box assessment, use a non-personal device:
117
118- Burp Suite / mitmproxy as system proxy on the test device — observe API traffic
119- Bypass SSL pinning with Frida + `objection` if you need to see encrypted traffic during testing
120- Modify requests, replay them, look for IDOR / BFLA (see `api-audit`)
121- Force background → resume to test session handling and screenshot blur
122- Force-quit → relaunch to test session persistence and auto-login
123- Install a malicious sibling app and test IPC paths (Android Intent fuzzing)
124
125## Output Format
126
127```markdown
128# Mobile Application Security Audit
129## App: [name + version]
130## Platform: iOS / Android / both
131## MASVS profile: L1 / L2 / R (resilience required)
132## Date: [date]
133
134### Executive summary
135[2-3 paragraphs]
136
137### MASVS category findings
138| Category | Findings | Severity high-water mark |
139|---|---|---|
140| STORAGE | N | |
141| CRYPTO | N | |
142| NETWORK | N | |
143| AUTH | N | |
144| PLATFORM | N | |
145| CODE | N | |
146| RESILIENCE | N | (only if R-profile) |
147
148### Per-finding detail
149[Title, MASVS-ID, severity, description, location, evidence, remediation, verification]
150
151### Backend API findings
152[Cross-link to api-audit / owasp-audit output]
153
154### Recommendations
155[Prioritized 30/60/90 day fixes]
156```
157
158## Boundaries
159
160- Audit only apps you own or have written authorization to test
161- Reverse-engineering a competitor's app is a legal risk — refuse unless the user can show authorization
162- Frida / Objection / SSL-pinning bypass are for your own apps in test environments — they are not "test in production" tools
163- Refuse to help build malware, surveillance apps, or stalkerware
164- If the audit surfaces evidence of an active backdoor in someone else's code, escalate; don't quietly fix and forget
165
166## References
167
168- OWASP MASVS (Mobile Application Security Verification Standard)
169- OWASP MASTG (Mobile Application Security Testing Guide)
170- OWASP Mobile Top 10
171- Apple Security: Apple Platform Security Guide
172- Android Security: Android Security Best Practices
173- iOS App Programming Guide — Security
174- "iOS Application Security" — David Thiel
175- "Android Hacker's Handbook"