Documentation Index
Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
Use this file to discover all available pages before exploring further.
Module Overview
Estimated Time: 4 hours | Difficulty: Advanced | Prerequisites: Authentication, Storage modules
- Secure storage solutions
- Certificate pinning
- Code obfuscation
- Jailbreak/root detection
- Data encryption
- Security auditing
Security Threat Model
Secure Storage
The most common security mistake in React Native apps is storing sensitive data (auth tokens, API keys, user credentials) in AsyncStorage or plain files. AsyncStorage is backed by an unencrypted SQLite database on Android and an unencrypted plist on iOS — anyone with physical device access (or a jailbroken device) can read it trivially. Secure storage uses the platform’s hardware-backed security: iOS Keychain and Android Keystore. Data stored here is encrypted at the OS level, protected by the device lock, and inaccessible to other apps.expo-secure-store
For sensitive data like tokens and credentials:react-native-keychain (CLI)
For React Native CLI projects:Encrypted Storage with MMKV
Certificate Pinning
Standard HTTPS validates that a server’s certificate was issued by a trusted Certificate Authority (CA). But what if an attacker compromises a CA, or installs a rogue root certificate on the user’s device (common in corporate environments or jailbroken devices)? They could issue a valid-looking certificate for your API domain and intercept all traffic. Certificate pinning solves this by telling your app to trust only specific certificates or public keys for your domain, not the entire CA chain. Think of it as adding a secret handshake on top of the standard TLS process.Using react-native-ssl-pinning
Using Axios with Certificate Pinning
Code Obfuscation
Your React Native app’s JavaScript bundle can be extracted from the APK/IPA file in minutes. Without obfuscation, an attacker can read your business logic, API endpoints, validation rules, and any hardcoded strings in plain text. Obfuscation does not make reverse engineering impossible — it makes it expensive and time-consuming enough to deter casual attackers.JavaScript Obfuscation
Android ProGuard
Jailbreak/Root Detection
Jailbroken (iOS) and rooted (Android) devices have their security sandbox removed. On these devices, other apps can read your app’s data, inject code, or attach debuggers. Detection is not foolproof — sophisticated users can bypass it — but it raises the bar and lets you make informed decisions about what functionality to allow. The practical question is: should you block jailbroken devices entirely, or just restrict sensitive features? Most apps take the second approach: banking and payment features require a secure device, but browsing and reading do not.Security Provider Component
Data Encryption
Sometimes you need to store structured data (not just simple strings) securely. Secure Store and Keychain have size limits and are designed for small values like tokens. For larger data — like cached user profiles, draft messages, or offline records that contain PII — you need application-level encryption on top of regular storage. The pattern: generate an encryption key on first launch, store it in Secure Store (hardware-protected), and use it to encrypt/decrypt data before writing to AsyncStorage or MMKV.Encrypting Sensitive Data
Biometric Authentication
Biometric auth (Face ID, Touch ID, fingerprint) does not replace password authentication — it provides a faster way to re-authenticate returning users. The typical flow: user logs in with email/password on first use, tokens are stored in Secure Store protected by biometric access control, and subsequent launches prompt for biometric verification to unlock the stored tokens.Biometric Login Component
Preventing Screenshot/Screen Recording
For financial, healthcare, or enterprise apps, preventing screenshots and screen recordings protects sensitive data from being casually shared. Android supports programmatic prevention via theFLAG_SECURE window flag. iOS does not support prevention (Apple intentionally prevents this), but you can detect screenshots and respond (show a warning, log a security event, or blur sensitive content).
Choosing the Right Storage for Sensitive Data
The most common security mistake is using the wrong storage mechanism for the sensitivity level of the data. Here is a decision matrix:| Data Type | Examples | Recommended Storage | Why |
|---|---|---|---|
| Auth tokens | Access tokens, refresh tokens, session IDs | expo-secure-store / react-native-keychain | Hardware-backed encryption, protected by device lock |
| User credentials | Passwords, PINs (if stored at all) | react-native-keychain with biometric access control | Keychain is the only appropriate location; prefer not storing passwords at all |
| Encryption keys | App-level encryption keys, API signing keys | expo-secure-store (generated on device, never transmitted) | Secure Store/Keychain is tamper-resistant; keys never leave the secure enclave |
| Cached PII | User profiles, health data, financial records | MMKV with encryption (key stored in Secure Store) | Too large for Secure Store (2KB limit on iOS); encryption-at-rest via derived key |
| Non-sensitive preferences | Theme, language, onboarding completion | AsyncStorage or MMKV (unencrypted) | No security risk; fast read/write for frequently accessed settings |
| Temporary data | Form drafts, search history, undo stack | In-memory (React state or Zustand) | Automatically cleared on app close; no persistence needed |
Certificate Pinning Decision Framework
Certificate pinning adds meaningful security but introduces operational complexity. Not every app needs it.| App Category | Pinning Recommendation | Rationale |
|---|---|---|
| Banking / financial | Required — pin to leaf or intermediate CA public key | Regulatory compliance; high-value target for MITM attacks |
| Healthcare / HIPAA | Required — pin to intermediate CA public key | Protected health information; compliance mandates |
| Enterprise / MDM-managed | Pin to intermediate CA — NOT leaf | Corporate environments often install custom root CAs; leaf pinning breaks MDM inspection |
| E-commerce | Recommended — pin to intermediate CA public key | Payment data in transit; balance security with rotation flexibility |
| Social / content | Optional — standard TLS is usually sufficient | Lower-value target; pinning adds rotation burden without proportional security gain |
| Internal / prototype | Skip — not worth the operational overhead | Focus development effort elsewhere; standard HTTPS is adequate |
| Pin Target | Rotation Frequency | Security Level | Operational Risk |
|---|---|---|---|
| Leaf certificate | Every 90 days to 1 year | Highest — only your exact cert is trusted | Highest — every cert rotation requires an app update |
| Intermediate CA | Every 3-5 years | High — trusts certs from one specific CA | Medium — you can rotate leaf certs freely |
| Root CA | Every 10-20 years | Moderate — trusts all certs from that CA chain | Low — rarely needs updating |
Edge Cases in Mobile Security
Token Refresh Race Condition
When multiple API calls fail simultaneously with a 401 (expired token), each one independently triggers a token refresh. This can cause multiple refresh requests, and if the server invalidates the refresh token on first use (which it should for security), all but the first refresh call fail — cascading into a forced logout.Clipboard Data Leakage
When users copy sensitive data (account numbers, one-time codes), it sits on the system clipboard accessible to any app. On Android, clipboard managers can even persist clipboard history across app switches.Deep Link Injection
Deep links (myapp://reset-password?token=xyz) can be crafted by malicious apps or websites to inject parameters into your navigation. If your app blindly trusts deep link parameters, an attacker can bypass auth flows or trigger unintended actions.
Background App Snapshot Exposure
Both iOS and Android capture a screenshot of your app when it moves to the background (for the app switcher). If your app displays sensitive data (bank balances, health records, personal messages), this screenshot is visible to anyone who opens the task switcher.Security Checklist
Storage Security
- Use SecureStore for tokens
- Encrypt sensitive data
- Clear data on logout
- No hardcoded secrets
Network Security
- Use HTTPS only
- Implement certificate pinning
- Validate SSL certificates
- Add request signing
Code Security
- Enable ProGuard/R8
- Remove debug logs
- Obfuscate JavaScript
- No sensitive data in logs
Runtime Security
- Detect jailbreak/root
- Prevent debugging
- Screen capture protection
- Clipboard security
Security Audit Script
Next Steps
Module 32: Offline-First Architecture
Learn to build apps that work seamlessly without internet connectivity