Keychain/Keystore used for sensitive data storage
Why it matters
Platform secure storage (iOS Keychain, Android Keystore) is backed by hardware security modules on modern devices — credentials stored there cannot be extracted even with root access because the decryption key never leaves the secure enclave. CWE-312 (Cleartext Storage of Sensitive Information) and CWE-522 (Insufficiently Protected Credentials) both apply when an app stores tokens outside these APIs. OWASP A02 and NIST SC-28 require encryption at rest for all authentication credentials. Apps without Keychain/Keystore usage have no encrypted credential store by definition — every stored secret is as secure as the device filesystem, which is not secure at all on rooted or cloned devices. This is the class of vulnerability that drives credential-stuffing campaigns after device theft.
Severity rationale
Critical because the total absence of Keychain or Keystore usage means no credential is encrypted at rest, making stored tokens recoverable via filesystem access on any rooted or backed-up device — a direct CWE-312 and OWASP A02 violation.
Remediation
Ensure every sensitive value flows through expo-secure-store or native Keychain/Keystore. Audit all storage calls and confirm zero sensitive values in AsyncStorage, MMKV, or localStorage.
// Expo (wraps Keychain on iOS, EncryptedSharedPreferences on Android)
import * as SecureStore from 'expo-secure-store'
async function storeSession(token: string, userId: string) {
await SecureStore.setItemAsync('session_token', token)
await SecureStore.setItemAsync('user_id', userId)
}
async function clearSession() {
await SecureStore.deleteItemAsync('session_token')
await SecureStore.deleteItemAsync('user_id')
}
For bare React Native, use react-native-keychain: Keychain.setGenericPassword(username, password). For large encrypted blobs, use react-native-mmkv with an encryption key stored in Keychain — not a hardcoded key.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Mobile Permissions & Privacy Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-312 — Cleartext Storage of Sensitive Information
- cwe · CWE-522 — Insufficiently Protected Credentials
- owasp:2021 · A02 — Cryptographic Failures
- nist:rev5 · SC-28 — Protection of Information at Rest
Taxons
History
- 2026-04-18·v1.0.0·Initial import from mobile-permissions-privacy·automated