Conducting a security audit of a mobile application
The audit doesn't start with running tools, but with understanding what exactly we're protecting. A fintech app with biometric authorization and a medical tracker writing to HealthKit — different threat models, different check priorities, different scope.
Standard reference point — OWASP Mobile Top 10. But this isn't a checklist for a checkmark, it's a structure for covering major vulnerability classes.
Static analysis (SAST)
First stage — analysis without running the app. APK decompilation via apktool + jadx gives readable Java/Kotlin code. For iOS — IDA Pro or Ghidra for binary, class-dump for Objective-C headers, strings for hardcoded secrets search.
What we look for statically:
- Hardcoded credentials: API keys, tokens, passwords in strings.
grep -r "api_key\|secret\|password" --include="*.java"finds obvious, but jadx shows deobfuscated code where it's baked into class constants - Unsafe storage: using
SharedPreferencesorUserDefaultsfor sensitive data, SQLite without encryption - Wrong Android component flags:
exported="true"on Activity/Service/BroadcastReceiver without proper intent-filter validation opens deep link and inter-process communication attacks - Weak cryptography:
DES,MD5for passwords,ECB mode, zero IV, predictableRandomseed
On Flutter apps SAST is harder — Dart compiles to native code via dart compile. Use reFlutter to patch engine and dump snapshots, then dumpapp to recover symbols.
Dynamic analysis (DAST)
Run the app on rooted Android (Magisk + LSposed) or jailbroken iOS (Checkra1n/Unc0ver) and watch runtime behavior.
Network traffic. Burp Suite as proxy, certificate added to system storage. If app uses Certificate Pinning — bypass via Frida script, hooking TrustManager or SSLPinningMode. After decrypting traffic, check: are sensitive data sent in query parameters (logged by servers), is authentication on all API endpoints, are correct headers (Strict-Transport-Security, X-Content-Type-Options).
File system. objection — framework based on Frida — allows real-time file viewing created by app: env print shows all directories, file cat reads contents. Look for unencrypted databases, logs with personal data, cached API responses.
Memory. fridump dumps app heap. In memory data often lives longer than needed: credentials after logout, decrypted payloads, private keys. Search patterns via strings on dump.
Reverse engineering and runtime tampering. Check if protections work: jailbreak/root detection, anti-debugging, certificate pinning. If everything is bypassed in 10 minutes with standard Frida scripts — protection level is minimal.
Typical findings by category
Most common: hardcoded Firebase or AWS keys in strings.xml or GoogleService-Info.plist, missing Certificate Pinning in fintech apps, logging API requests with tokens via Log.d (remains in production), unsafe deep link handlers without source validation, missing privacy screen on app backgrounding (FLAG_SECURE / UIScreen.main.brightness).
Rarer but more critical: SQL injection via deep link parameters, unsafe deserialization in broadcast receivers, ability to bypass biometrics by patching BiometricPrompt result.
Reporting and classification
Each finding gets CVSS score and attack vector description — not just "found vulnerability", but "attacker with physical device access can in 15 minutes extract authorization token from unencrypted database and use it to access API". Each point — specific fix recommendation with code example.
Final report divided into two parts: technical (for developers, with code, screenshots, Frida scripts) and executive (for managers, with priorities and business risks).
Process and timelines
Minimal audit of small app (up to 50 screens, no complex business logic) — 1–2 weeks. Comprehensive audit of enterprise app with server part, multiple platforms and compliance requirements (PCI DSS, HIPAA) — up to 2–3 months. Pricing calculated after initial analysis: need to understand scope of functionality, platforms (iOS, Android, both), whether server is in scope.
After audit we offer retest — verification that found vulnerabilities are actually closed, not just marked as fixed.







