Mobile App Security: Protecting User Data in iOS and Android Applications
A comprehensive security guide for mobile developers covering secure data storage, certificate pinning, code obfuscation, and API security for mobile applications.
Mobile Apps Are High-Value Targets
Mobile applications handle some of the most sensitive user data: banking credentials, personal photos, health records, location history, and biometric data. Unlike web applications where the server controls the environment, mobile apps run on devices that users control — devices that might be jailbroken, connected to compromised Wi-Fi networks, or infected with malware. This fundamentally different threat model requires a defense-in-depth approach to security.
Secure Data Storage
Never store sensitive data in plaintext on the device. Mobile operating systems provide secure storage mechanisms specifically designed for sensitive information:
- iOS Keychain: The iOS Keychain is a hardware-backed encrypted database for storing passwords, tokens, and cryptographic keys. Data stored in the Keychain is encrypted using a key derived from the device's unique hardware ID and the user's passcode, making it resistant to extraction even from device backups.
- Android Keystore: The Android Keystore system stores cryptographic keys in a container that makes them more difficult to extract from the device. On devices with a Trusted Execution Environment (TEE) or Secure Element (SE), keys are stored in hardware, providing protection even if the operating system is compromised.
- Encrypted SharedPreferences (Android) / UserDefaults (iOS): For non-cryptographic data that still requires confidentiality, use EncryptedSharedPreferences (from the Android Jetpack Security library) or encrypt data before writing to UserDefaults.
What NOT to Store on the Device
- Full credit card numbers — use tokenization instead.
- Passwords in any form — store authentication tokens with expiration.
- API keys or secrets — these belong on your server, not in the client.
- Sensitive business logic — if it is in the client binary, it can be reverse-engineered.
Network Security
Certificate Pinning
HTTPS encrypts data in transit, but it can be circumvented by Man-in-the-Middle (MitM) attacks using rogue certificates. Certificate Pinning binds your app to a specific server certificate (or its public key hash), rejecting connections to servers presenting any other certificate — even if it is signed by a trusted Certificate Authority.
On iOS, implement pinning using URLSessionDelegate's challenge handler. On Android, configure it in the Network Security Configuration XML file. Be cautious: improper pinning can lock users out of your app if you rotate certificates without updating the app. Always pin the public key rather than the full certificate, and include a backup pin.
API Security
- Short-lived Access Tokens: Use JWTs with 15-minute expiration, refreshed via a secure refresh token flow. If an access token is stolen, the window of exploitation is minimal.
- Request Signing: For high-security APIs (banking, payments), sign each request with an HMAC using a secret stored in the device's secure enclave. The server verifies the signature, preventing request tampering.
- Input Validation: Validate and sanitize all data on the server side. Never trust data from the mobile client — it can be modified by an attacker using a proxy tool like Charles or Burp Suite.
Code Protection
Obfuscation
Android apps (especially those written in Java/Kotlin) can be easily decompiled using tools like JADX. Use ProGuard or R8 to obfuscate class names, method names, and string literals, making reverse engineering significantly harder. For React Native apps, use tools like react-native-obfuscating-transformer.
Root/Jailbreak Detection
Apps running on rooted (Android) or jailbroken (iOS) devices are at elevated risk because security controls enforced by the operating system have been bypassed. Implement root/jailbreak detection to warn users or restrict functionality on compromised devices. Libraries like RootBeer (Android) and IOSSecuritySuite (iOS) provide reliable detection mechanisms.
Tamper Detection
Detect if the app's binary has been modified (repackaged with malicious code) by verifying the app's signing certificate at runtime. On Android, compare the package signature hash against a known-good value. On iOS, verify the embedded provisioning profile.
Biometric Authentication
Biometric authentication (fingerprint, face recognition) should complement, not replace, traditional authentication. Use the platform's biometric APIs (LocalAuthentication on iOS, BiometricPrompt on Android) to unlock a cryptographic key stored in the secure enclave, which is then used to decrypt a stored authentication token. This ensures that even if the biometric system is bypassed, the attacker still needs the hardware-protected key.
Conclusion
Mobile security is a layered discipline. No single technique provides complete protection, but combining secure storage, network security, code protection, and runtime checks creates a defense-in-depth strategy that significantly raises the bar for attackers. Conduct regular security audits, use automated scanning tools (MobSF, Checkmarx), and stay updated on platform-specific security advisories.

