Insecure Storage
One of the most common and easy-to-find flaw classes in mobile apps is storing sensitive data —tokens, passwords, keys, PII, session information— on the device unencrypted or in accessible locations. Since the device can be rooted/jailbroken (or backed up), anything the app writes in the clear is exposed. It’s the MASVS-STORAGE category and almost always produces findings.
Where each platform stores
Section titled “Where each platform stores”Android
Section titled “Android”/data/data/<package>/ shared_prefs/*.xml SharedPreferences (key-value, often cleartext) databases/*.db SQLite (app data) files/ internal files cache/ cache# external storage (accessible by other apps / weak sandbox)/sdcard/Android/data/<package>/# the correct place for secrets:Android Keystore hardware-backed keys (TEE/StrongBox)/var/mobile/Containers/Data/Application/<UUID>/ Library/Preferences/*.plist NSUserDefaults (key-value, cleartext) Documents/, Library/, tmp/ files, SQLite, cache# the correct place for secrets:Keychain system encrypted store (with protection classes)Access the data (Android)
Section titled “Access the data (Android)”# with root or run-as (if the app is debuggable)adb shell run-as com.target cat /data/data/com.target/shared_prefs/prefs.xmladb shell "su -c 'ls -la /data/data/com.target/'"# databasesadb pull /data/data/com.target/databases/app.db ; sqlite3 app.db# backup (if allowBackup=true, no root)adb backup -f backup.ab com.target ; (abe.jar to extract)# Objectionandroid keystore list ; android hooking ... # inspectAccess the data (iOS)
Section titled “Access the data (iOS)”# with jailbreak, SSH to the device or Objectionobjection -g com.target.app exploreios keychain dump # Keychain dumpenv # app container pathsls /var/mobile/Containers/Data/Application/<UUID>/# NSUserDefaults .plist, SQLite, cacheWhat to look for
Section titled “What to look for”session tokens / JWT, passwords, API keys, PINsencryption keys stored next to the encrypted data (classic mistake)PII (personal data), card data, messages# in any format: SharedPreferences/plist, SQLite, files, cache, logsgrep -riE 'token|password|secret|key|BEGIN' /data/data/com.target/Less obvious leaks
Section titled “Less obvious leaks”# logs: the app writes sensitive data to logcat / NSLogadb logcat | grep -i target# keyboard cache, pasteboard (iOS), background screenshots (snapshot on minimize)# WebView cache, uncleaned in-memory data# cloud backups (iCloud/Google Backup) including sensitive dataFor the defense
Section titled “For the defense”- Secrets in the secure store: Android Keystore / iOS Keychain (with the right protection class), never in SharedPreferences/NSUserDefaults/cleartext files.
- Don’t store what you don’t need: minimize on-device data; short-lived tokens.
- Correct encryption: don’t store the key next to the data; use non-extractable (hardware-backed) keys.
- allowBackup=false (Android), exclude sensitive data from backups; Data Protection (iOS).
- Don’t log sensitive data; clear cache/pasteboard; protect the background snapshot.
Testing checklist
Section titled “Testing checklist”- Locate the app’s data directories (Android/iOS)
- SharedPreferences / NSUserDefaults in cleartext
- SQLite databases with sensitive data
- Files, cache, and external storage
- Keystore/Keychain: used? protection class?
- Encryption keys stored next to the data
- Leaks in logs, pasteboard, background screenshots, backups
- allowBackup/extractable backup (Android)