Data Security
⚡ Intermediate
Insecure Local Storage
Mobile apps frequently store sensitive data locally without proper encryption. This guide covers identifying and exploiting insecure data storage on both Android and iOS platforms.
OWASP M2: Insecure Data Storage
Insecure data storage is the #2 risk in the OWASP Mobile Top 10. Sensitive data stored in plaintext
or with weak encryption can be extracted from lost/stolen devices, malware, or forensic analysis.
Android Storage Locations
SharedPreferences
XML files storing key-value pairs. Often contain tokens, credentials, and settings:
bash
# Location on device
/data/data/<package>/shared_prefs/
# List all SharedPreferences files
adb shell run-as com.target.app ls shared_prefs/
# Read preferences (rooted device)
adb shell cat /data/data/com.target.app/shared_prefs/*.xml
# Using Frida to dump SharedPreferences
Java.perform(function() {
var context = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext();
var prefs = context.getSharedPreferences("app_prefs", 0);
var all = prefs.getAll();
var it = all.entrySet().iterator();
while (it.hasNext()) {
var entry = it.next();
console.log(entry.getKey() + ": " + entry.getValue());
}
});SQLite Databases
Local databases often store user data, messages, and cached content:
bash
# Database location
/data/data/<package>/databases/
# Pull database
adb shell run-as com.target.app cat databases/app.db > app.db
# Or on rooted device
adb pull /data/data/com.target.app/databases/app.db
# Analyze with SQLite
sqlite3 app.db
.tables
.schema users
SELECT * FROM users;
# Look for sensitive data
SELECT * FROM sqlite_master WHERE type='table';Internal Files
bash
# Internal storage location
/data/data/<package>/files/
/data/data/<package>/cache/
# List all files
adb shell run-as com.target.app find . -type f
# Search for sensitive patterns
adb shell run-as com.target.app grep -r "password|token|key|secret" files/
# Check file permissions
adb shell run-as com.target.app ls -la files/External Storage (World-Readable)
High Risk
Data stored on external storage (SD card) is readable by any app with storage permissions.
bash
# External storage locations
/sdcard/
/sdcard/Android/data/<package>/
# Search for app data
adb shell find /sdcard -name "*target*" 2>/dev/null
# Check for exported files
adb shell ls -la /sdcard/Android/data/com.target.app/iOS Storage Locations
Keychain
iOS secure storage. Can be dumped on jailbroken devices:
bash
# Using keychain-dumper (on device)
./keychain-dumper
# Using Objection
objection -g com.target.app explore
ios keychain dump
# Using Frida
ObjC.schedule(ObjC.mainQueue, function() {
var query = ObjC.classes.NSMutableDictionary.alloc().init();
query.setObject_forKey_(ObjC.classes.kSecClassGenericPassword, "class");
query.setObject_forKey_(ObjC.classes.kSecMatchLimitAll, "limit");
query.setObject_forKey_(true, "returnData");
var result = ObjC.classes.SecItemCopyMatching(query, null);
console.log(result);
});NSUserDefaults / Plist Files
bash
# Plist locations
/var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/
# Read plist files
plutil -p /path/to/com.target.app.plist
# Using Objection
ios plist cat com.target.app.plist
# Frida to dump NSUserDefaults
Java.perform(function() {
var NSUserDefaults = ObjC.classes.NSUserDefaults;
var defaults = NSUserDefaults.standardUserDefaults();
var dict = defaults.dictionaryRepresentation();
console.log(dict.toString());
});SQLite & Core Data
bash
# Database locations
/var/mobile/Containers/Data/Application/<UUID>/Documents/
/var/mobile/Containers/Data/Application/<UUID>/Library/
# Find all databases
find /var/mobile/Containers/Data/Application/<UUID> -name "*.sqlite" -o -name "*.db"
# Copy to computer
scp root@device:/path/to/database.sqlite .
# Analyze
sqlite3 database.sqlite
.tables
SELECT * FROM sensitive_table;Cache & Cookies
bash
# Cache locations
/var/mobile/Containers/Data/Application/<UUID>/Library/Caches/
# Cookies database
/var/mobile/Containers/Data/Application/<UUID>/Library/Cookies/Cookies.binarycookies
# Using Objection
ios cookies get
# Check for sensitive cached data
find /var/mobile/Containers/Data/Application/<UUID>/Library/Caches -type f -exec file {} \;Automated Analysis
Android - Objection Commands
bash
# Explore the app
objection -g com.target.app explore
# List files in app directory
env
android root disable # If needed
# SQLite commands
sqlite connect app.db
sqlite execute query SELECT * FROM users;
# Monitor file system access
android filesystem watch /data/data/com.target.app/iOS - Objection Commands
bash
# Connect to app
objection -g com.target.app explore
# Environment info
env
# Dump keychain
ios keychain dump
# Get cookies
ios cookies get
# List bundles
ios bundles list
# Dump NSUserDefaults
ios nsuserdefaults getSecurity Comparison
| Storage | Encrypted | Accessible | Risk |
|---|---|---|---|
| Android Keystore | Yes (hardware-backed) | Root + app context | Low |
| iOS Keychain | Yes (SEP) | Jailbreak + tools | Low |
| SharedPreferences | No (plaintext XML) | Root or backup | Medium |
| NSUserDefaults | No (plaintext plist) | Jailbreak or backup | Medium |
| SQLite | No (unless SQLCipher) | Root/jailbreak | Medium |
| External Storage | No | Any app | High |
Sensitive Data to Find
Authentication Data
- • Usernames and passwords
- • Session tokens / JWT
- • API keys
- • OAuth tokens
- • Remember me tokens
Personal Information
- • Names, emails, phone numbers
- • Credit card data
- • Health information
- • Location history
- • Private messages
Cryptographic Material
- • Private keys
- • Encryption keys
- • Certificates
- • Encryption IVs
Application Data
- • Backend URLs
- • Debug flags
- • Feature toggles
- • Internal IDs
Reporting Findings
When reporting insecure storage issues, include: the exact file/database location, what sensitive
data was found, how it could be accessed (root vs non-root), and the potential impact of exposure.