Mobile
What a mobile app security review checks closely: MASVS, MASWE and OWASP Mobile Top 10
Which standards a mobile app security review relies on and which weaknesses it finds in practice. The 9 findings from our own app, grouped by severity.
· 7 min read

A team that has already passed a website security review may assume the mobile app will be checked the same way. In practice a mobile review works differently: the subject is not a server but the app itself, running on a device in the user's hands. The reviewer takes the APK or IPA, unpacks it, runs it on an emulator and a rooted device, intercepts its traffic and tests the app's built-in defences.
In this article we look at the standards a mobile review relies on, and at the 9 findings from the review of our own product — the Android and iOS apps of a tax and finance SaaS platform, built with Flutter. All findings have been closed.
Which standards are used
Mobile reviews usually rely on the OWASP mobile documents:
- OWASP MASVS (Mobile Application Security Verification Standard) — defines the requirements an app should meet. They are grouped into data storage (STORAGE), cryptography (CRYPTO), authentication (AUTH), network (NETWORK), platform interaction (PLATFORM), code quality (CODE), resilience against reverse engineering (RESILIENCE) and privacy (PRIVACY).
- OWASP MASTG (Mobile Application Security Testing Guide) — a practical guide on how to test each requirement.
- OWASP MASWE (Mobile Application Security Weakness Enumeration) — a numbered catalogue of mobile weaknesses. Findings in a review report usually carry this number, for example MASWE-0097 (root or jailbreak detection not implemented).
- OWASP Mobile Top 10 (2024) — the most common risk categories, M1 to M10. Findings are often mapped to these as well, for example M7 Insufficient Binary Protections.
- CWE — the general weakness classification, especially for cryptography and certificate validation issues.
The key difference: a web review focuses mostly on the server, while in a mobile review the RESILIENCE group — the app's ability to protect itself — carries special weight.
What was found in practice: 9 findings
Below are the findings from the review report on our app, grouped by severity.
Android — HIGH
- Root detection not implemented. The app ran on a rooted device without any warning. The report marked it as MASWE-0097 and OWASP Mobile Top 10 2024 M7.
- Sensitive data stored unencrypted in internal storage. Anyone with root access could open the app folder and read the tokens.
- No app integrity (tamper) check. If the APK was rebuilt and installed with a different signature, the app did not notice.
- Insecure certificate validation. The app accepted any certificate the system trusted, so traffic could be intercepted through a third-party CA installed on the device.
- No protection against dynamic analysis tools. Tools such as Frida could change the app's functions at runtime.
Android — MEDIUM
- Emulator detection not implemented. The app ran fully on an emulator, which makes analysis and automated attacks easier.
Android — LOW
- Insecure (http) links. Unencrypted addresses had been left in the code.
iOS — HIGH
- No protection against dynamic analysis. As on Android, the iOS app did not detect hooking tools.
- Jailbreak detection not implemented. The iOS equivalent of root.
As you can see, most of the 9 findings are not coding bugs but a missing protection layer. The app works correctly, it just does not defend itself.
How they were closed
Instead of a separate fix for each finding, several complementary layers were applied:
- A RASP library (freeRASP) — detects root, jailbreak, emulators, hooks, debuggers and tampering. When a threat is detected, the user sees a blocking warning screen.
- Certificate pinning — the app trusts only selected root CAs: on the Dart side a
SecurityContextwith trusted roots only, on Android apin-setinnetwork_security_config. - Secure storage —
flutter_secure_storageon top of Android Keystore and iOS Keychain. - Obfuscation — R8 minify for Android and
--obfuscatefor the Dart code. - Backup protection —
allowBackup=falseanddata_extraction_rules. - Network — cleartext (http) traffic is fully disabled, and API endpoints are not stored as plain strings in the code.
- Cleanup on logout — WebView data is wiped when the user logs out.
Each of these topics has its own article on the blog: root/jailbreak detection, SSL pinning, Keystore and Keychain, Frida and RASP.
What else you need before submitting
The review also asks for checksums of the submitted APK and IPA: MD5, SHA1 and SHA256. They confirm that the reviewed file is exactly the one that will be published to the store. You can get them with simple commands:
md5sum app-release.apk
sha1sum app-release.apk
sha256sum app-release.apk
On macOS use shasum -a 1 and shasum -a 256. Keep in mind that the values change whenever the file is rebuilt, so take the checksums from the exact final build you submit.
A practical checklist
Before sending the app for review, check these yourself:
- What does the app do on a rooted or jailbroken device?
- Does it start on an emulator, and is that intended?
- Where are tokens, passwords or personal data stored — SharedPreferences, UserDefaults, or Keystore/Keychain?
- Can traffic be intercepted if a third-party CA is installed on the device?
- Will the app notice if the APK is rebuilt with a different signature?
- Are there any addresses starting with
http://left in the code? - Is the release build obfuscated?
- Is
allowBackupdisabled?
If the answer to any of these is unclear, that is exactly where the review will find something.
Conclusion
A mobile review checks not what the app does, but how well it is protected. Most findings can be closed in a few days of work if they are planned for. It is better to add these layers while the app is being prepared than to wait for the review report and only then start fixing.
If you want to know how ready your app is for the review, request a security scan. The Claude AI agent and our specialist will look through your APK or IPA, show the weaknesses they find and help you close them.


