AsyncStorage in React Native is unencrypted plaintext on every platform — its contents are readable from a jailbroken iOS device or from any app on Android versions below 4.4. Storing auth tokens, JWTs, or user PII in AsyncStorage means a single compromised device exposes session credentials that can be replayed to impersonate the user with full account access. OWASP 2021 A02 (Cryptographic Failures), CWE-312 (Cleartext Storage of Sensitive Information), HIPAA §164.312(a)(2)(iv), and NIST SP 800-218 PW.4 all require sensitive data at rest to be encrypted using platform-provided mechanisms (Keychain on iOS, Keystore on Android).
High because auth tokens in AsyncStorage are accessible to any process on a compromised device, enabling session hijacking and full account takeover without a network attack.
Replace AsyncStorage for sensitive data with expo-secure-store, which uses Keychain on iOS and EncryptedSharedPreferences on Android:
import * as SecureStore from 'expo-secure-store';
// Store
await SecureStore.setItemAsync('authToken', token);
// Retrieve
const token = await SecureStore.getItemAsync('authToken');
For non-Expo React Native, use react-native-keychain:
import * as Keychain from 'react-native-keychain';
await Keychain.setGenericPassword('token', jwtValue);
Search for every AsyncStorage.setItem call in src/ and audit what is being stored. Move tokens and PII to secure storage; leave only non-sensitive preferences (theme, language) in AsyncStorage.
app-store-privacy-data.data-handling.sensitive-data-encryptionhighAsyncStorage (React Native) is plaintext and unencrypted — any data stored there is readable from a jailbroken/rooted device and accessible to other apps on older Android versions. Search for AsyncStorage.setItem calls that store: auth tokens, session tokens, refresh tokens, JWT, API keys, user PII (name, email, phone, address), health data, financial data, or any object stringified with JSON.stringify() containing these fields. Compare against encrypted alternatives: expo-secure-store (Keychain on iOS, EncryptedSharedPreferences on Android), react-native-keychain (Keychain on iOS, Keystore on Android), @react-native-async-storage/async-storage combined with rn-encrypted-storage. For Flutter, look for shared_preferences storing sensitive data vs. flutter_secure_storage. For native iOS, look for UserDefaults storing tokens vs. Keychain (SecItemAdd). Flag: auth tokens in AsyncStorage; raw JWTs stored in localStorage-equivalent; any string containing "token", "secret", "key", "password", "ssn", "creditCard" stored in plaintext storage.AsyncStorage or SharedPreferences.AsyncStorage, SharedPreferences, or equivalent unencrypted storage."JWT token stored via AsyncStorage.setItem('authToken', token) in src/services/auth.ts — AsyncStorage is unencrypted plaintext on all platforms" or "User profile including email and phone stored in AsyncStorage via JSON.stringify — sensitive PII in plaintext local storage"AsyncStorage for sensitive data with expo-secure-store:
import * as SecureStore from 'expo-secure-store';
// Store
await SecureStore.setItemAsync('authToken', token);
// Retrieve
const token = await SecureStore.getItemAsync('authToken');
react-native-keychain:
import * as Keychain from 'react-native-keychain';
await Keychain.setGenericPassword('token', jwtValue);
AsyncStorage.setItem call — move tokens and PII to secure storage, leave only non-sensitive preferences (theme, language) in AsyncStorage