Secure storage used for auth tokens and secrets
Why it matters
Storing JWT access tokens or refresh tokens in AsyncStorage or UserDefaults writes them as plaintext accessible to any process with filesystem access on a rooted device. CWE-312 (Cleartext Storage of Sensitive Information) and CWE-522 (Insufficiently Protected Credentials) both apply. NIST SP 800-53 IA-5 requires cryptographic protection of authenticators at rest. GDPR Art. 32 mandates appropriate technical measures for personal data — an unprotected refresh token is a credential, and its exposure enables persistent account takeover after the original access token expires.
Severity rationale
High because a plaintext refresh token in AsyncStorage on a compromised device grants an attacker persistent, renewable access to the user's account.
Remediation
Store all tokens exclusively in platform-secure storage. Implement a typed AuthTokenStorage class so there is no ambiguity about which storage API to use at call sites.
import * as SecureStore from 'expo-secure-store';
export class AuthTokenStorage {
private static ACCESS = 'access_token';
private static REFRESH = 'refresh_token';
static save(access: string, refresh: string) {
return Promise.all([
SecureStore.setItemAsync(this.ACCESS, access),
SecureStore.setItemAsync(this.REFRESH, refresh),
]);
}
static getAccess() { return SecureStore.getItemAsync(this.ACCESS); }
static getRefresh() { return SecureStore.getItemAsync(this.REFRESH); }
static clear() {
return Promise.all([
SecureStore.deleteItemAsync(this.ACCESS),
SecureStore.deleteItemAsync(this.REFRESH),
]);
}
}
Grep for AsyncStorage.setItem in your auth module and verify every match stores only non-sensitive data. The secure storage key names must not be hardcoded in a way that reveals their content (prefer opaque identifiers).
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 Offline & Storage 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
- gdpr · Art. 32 — Security of processing
- nist:rev5 · IA-5 — Authenticator Management
Taxons
History
- 2026-04-18·v1.0.0·Initial import from mobile-offline-storage·automated