Mobile Security: What Developers Consistently Get Wrong
Mobile security vulnerabilities cluster in a predictable set of categories. The same mistakes appear in security audits of consumer apps, enterprise apps, and fintech apps with equal regularity. The recurrence of the same errors across different teams and different organizations suggests that the failures are not primarily due to ignorance — most mobile developers are aware that security matters — but to a gap between security knowledge and the specific engineering practices that translate that knowledge into secure code.
The gap is widest in four areas: credential storage, certificate validation, data transmission, and third-party library management. Each has well-documented best practices. Each is routinely implemented incorrectly in production applications.
Credential Storage
The most common mobile security failure, and the one with the most direct impact on users, is improper credential storage. Authentication tokens, API keys, and user credentials stored in accessible locations — SharedPreferences on Android, UserDefaults on iOS, or local database tables without encryption — are recoverable by any attacker who gains access to the device’s storage, whether through physical access, a backup extraction, or a device vulnerability.
The correct approach is platform-provided secure storage: the Android Keystore and iOS Keychain. Both provide hardware-backed encryption when the device has a secure element, and software-backed encryption on devices without one. The APIs are somewhat awkward to use compared to simple key-value storage, which is the proximate reason developers avoid them — the path of least resistance leads to SharedPreferences or UserDefaults, which feel equivalent to the developer writing the code but are not equivalent from a security perspective.
The failure mode is particularly acute for long-lived tokens. An authentication token stored in UserDefaults that is valid for a year represents a year-long window of exposure for any user whose device is compromised. The same token stored in the Keychain with appropriate access controls — requiring biometric authentication for access, expiring when the device lock screen is disabled — represents a substantially smaller exposure.
Certificate Validation
Certificate pinning — the practice of hardcoding expected server certificates or public keys into the app and refusing connections that do not match — is frequently implemented with a failure mode that defeats its purpose. Pinning that catches certificate mismatches but fails open — connecting anyway and logging the mismatch — provides no security benefit. Pinning without a backup pin — a second certificate to use when the primary is rotated — causes app outages when certificate renewal is required.
The more common failure is the absence of pinning where it matters. Apps that handle sensitive financial data, health information, or authentication credentials benefit from certificate pinning in proportion to the sensitivity of the data they transmit. Consumer apps that transmit only public content do not benefit from the operational complexity pinning introduces. The risk assessment that determines where pinning is appropriate is rarely performed explicitly.
Data at Rest
Full-disk encryption on modern iOS and Android devices provides baseline protection for all data at rest. The protection is only as strong as the device passcode, because the encryption key is derived from the passcode. Apps that handle sensitive data and want stronger protection than the device baseline provides need to implement application-level encryption using keys that are stored in the secure element rather than derived from the passcode.
The practical implication is that apps handling data that would be damaging to users if disclosed — medical records, financial account information, messages — should not rely on the OS default encryption as their sole data protection layer. The additional implementation cost is modest. The additional protection is meaningful for users on devices with weak passcodes, which represents a significant portion of any consumer app’s user base.
Third-Party Libraries
The dependency supply chain is the security surface that has expanded most rapidly relative to developer awareness. Mobile apps routinely depend on dozens of third-party libraries, including SDKs from advertising networks, analytics providers, and crash reporting services. Each SDK represents code running in the app’s security context with access to the same data and capabilities as first-party code.
The permissions that analytics SDKs request, the data they collect, and the servers they transmit it to are frequently opaque to the developer integrating them. An advertising SDK that collects more user data than the app’s privacy policy discloses is a privacy violation that the developer may not have known about. An analytics SDK with a security vulnerability becomes a vulnerability in every app that integrates it.
Auditing third-party dependencies is unglamorous work that most teams defer until a specific incident forces the conversation. The incident, when it comes, is more expensive than the audit would have been.