Skip to content

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.

/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)
# with root or run-as (if the app is debuggable)
adb shell run-as com.target cat /data/data/com.target/shared_prefs/prefs.xml
adb shell "su -c 'ls -la /data/data/com.target/'"
# databases
adb 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)
# Objection
android keystore list ; android hooking ... # inspect
# with jailbreak, SSH to the device or Objection
objection -g com.target.app explore
ios keychain dump # Keychain dump
env # app container paths
ls /var/mobile/Containers/Data/Application/<UUID>/
# NSUserDefaults .plist, SQLite, cache
session tokens / JWT, passwords, API keys, PINs
encryption keys stored next to the encrypted data (classic mistake)
PII (personal data), card data, messages
# in any format: SharedPreferences/plist, SQLite, files, cache, logs
grep -riE 'token|password|secret|key|BEGIN' /data/data/com.target/
# logs: the app writes sensitive data to logcat / NSLog
adb 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 data
  • 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.
  • 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)