๐ What Is It?
Improper Credential Usage occurs when mobile applications store, transmit, or use authentication credentials (passwords, API keys, tokens, certificates) insecurely. This includes hardcoding credentials in source code, storing them in plain text, or exposing them through logs and error messages. Mobile apps are distributed binaries running on potentially compromised devices, making credential protection critical.
M01
OWASP Rank
78%
Apps Affected
<1hr
Time to Exploit
โ ๏ธ Common Exploits
- APK/IPA Decompilation: Extract hardcoded API keys from binaries
- String Analysis: Search for secrets in decompiled code
- Storage Inspection: Access credentials in SharedPreferences/Keychain
- Log Analysis: Extract tokens from application logs
- Memory Dumps: Capture credentials from runtime memory
- Backup Extraction: Access credentials from device backups
๐ด Attack Flow
1. Attacker downloads APK/IPA from store
โ
2. Decompiles with jadx/apktool/Hopper
โ
3. Searches for "api_key", "password", "secret"
โ
4. Extracts hardcoded credentials
โ
5. BREACH: Uses API keys to access backend!
โ
2. Decompiles with jadx/apktool/Hopper
โ
3. Searches for "api_key", "password", "secret"
โ
4. Extracts hardcoded credentials
โ
5. BREACH: Uses API keys to access backend!
โ Vulnerable Code
// Bad: Hardcoded API key (Android)
public class ApiClient {
// VULNERABLE: API key in source code
private static final String API_KEY = "AIzaSyDxVW2E9vZpQN7h8dK2eZvN9vZpQN7h8d";
public Response makeApiCall(String endpoint) {
client.addHeader("X-API-Key", API_KEY);
return client.get(endpoint);
}
}
// Bad: Plain text password storage
public void saveCredentials(String user, String pass) {
// VULNERABLE: Plain text in SharedPreferences
prefs.edit()
.putString("username", user)
.putString("password", pass)
.apply();
}
// Bad: Logging credentials (iOS)
func login(email: String, password: String) {
// VULNERABLE: Credentials in logs
print("Login attempt: \(email) / \(password)")
NSLog("Auth token: %@", authToken)
}
โ Secure Code
// Good: Use Android Keystore (Android)
public class SecureStorage {
private KeyStore keyStore;
public void storeToken(String token) {
// Encrypt using Android Keystore
SecretKey key = getOrCreateKey();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = cipher.doFinal(token.getBytes());
saveEncrypted(encrypted);
}
}
// Good: iOS Keychain with access control
func storeToken(_ token: String) {
let query: [String: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: "authToken",
kSecValueData: token.data(using: .utf8)!,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemAdd(query as CFDictionary, nil)
}
// Good: Fetch API keys from secure backend
public void getApiKey() {
// Request time-limited API key from backend
String deviceToken = getDeviceToken();
ApiKey key = backend.requestApiKey(deviceToken);
// Key expires in 24 hours, auto-rotates
}
โ Prevention Checklist
- Never hardcode API keys, secrets, or passwords
- Use Android Keystore or iOS Keychain for credentials
- Implement certificate pinning for API calls
- Remove all logging of sensitive data
- Use OAuth 2.0 with refresh tokens
- Implement token expiration and rotation
- Exclude credentials from device backups
- Use obfuscation for additional protection
- Implement runtime application self-protection (RASP)
- Regular security code reviews and penetration testing
๐ Detection & Tools
Analysis Tools:
MobSF
jadx
apktool
Frida
Objection
Hopper
IDA Pro
Ghidra
Prevention Tools:
Android Keystore
iOS Keychain
SafetyNet
ProGuard
R8
DexGuard
How to Test:
- Decompile APK with jadx/apktool or IPA with class-dump
- Search for strings: "api", "key", "secret", "password"
- Inspect SharedPreferences, NSUserDefaults, SQLite databases
- Monitor logs with adb logcat or Console.app
- Use Frida to hook credential storage functions
- Extract and analyze device backups
๐ Real-World Breaches
- Starbucks (2019): API keys hardcoded in mobile app allowed unauthorized access
- Popular VPN App (2020): Hardcoded AWS credentials leaked, exposing user data
- Dating Apps (2019): Multiple apps stored passwords in plain text locally
- Banking Apps (2018): Several banks stored PINs unencrypted in memory
- Social Media App (2021): OAuth tokens logged and accessible via device logs
๐ Quick Tips
- DO NOT hardcode any credentials in code
- DO NOT store passwords in plain text
- DO NOT log credentials or tokens
- DO use platform secure storage (Keystore/Keychain)
- DO implement certificate pinning
- DO use time-limited tokens with rotation
๐ Compliance
Related Standards:
- PCI-DSS Requirement 6.5.3, 8.2.1
- GDPR Art. 32 - Security of Processing
- HIPAA ยง164.312(a)(2)(iv)
- NIST 800-53 IA-5
- OWASP MASVS MSTG-STORAGE-14
- ISO 27001 A.9.4.3