menu
close_24px

BLOG

Unlocked & exposed: The hidden risks of Android app local storage

Learn how insecure local storage in Android apps exposes sensitive data through SharedPreferences, backups, SQLite, Realm, and Firebase. Discover best practices to secure storage, protect users, and prevent exploitation.
  • Posted on: Sep 23, 2025
  • By Prudhvi Chaitanya Depuru
  • Read time 6 Mins Read
  • Last updated on: Sep 23, 2025

Every Android app relies on local storage to function. Whether it’s user credentials, API tokens, cached data, or session details, applications often write sensitive information to the device. And every one of those storage points is a potential entryway for attackers if not properly secured.

The problem isn’t storage itself but how data is stored. Weak implementation choices expose critical information to attackers, malware, or even forensic tools. 

What’s insecure local storage in Android apps?

Insecure local storage is one of the most common Android security flaws flagged by OWASP MASVS-STORAGE and the Mobile Application Security Testing Guide (MASTG). Yet these security flaws are overlooked in Android development, making apps attractive targets for exploitation.

 In Android applications, data can be stored in various locations, including:

  • Shared Preferences
  • SQLite Databases
  • Keystore
  • Logging 
  • Backups
  • Realm Databases
  • Keyboard Caches
  • Firebase

Breaches exploiting such weak storage controls usually lead to massive data leaks, regulatory fines (GDPR, PCI-DSS), and reputational damage for global brands.

For developers, the risk is just as real — unencrypted SharedPreferences or SQLite databases can be dumped in minutes using adb or reverse engineering tools, exposing users’ sensitive data. For security leaders, the bigger challenge is proving compliance and securing apps without slowing releases.

In this guide, we’ll uncover the dark secrets of Android local storage:

  • Where sensitive data often hides (and leaks)
  • The top risks in SharedPreferences, SQLite, Realm, backups, and Firebase
  • How to prevent attackers from pulling your users’ data with just a cable or a script

By the end, you’ll have a clear playbook to secure local storage and harden your apps against one of the most common (and costly) mobile vulnerabilities.

Android insecure data storage: Key risks developers overlook

For app developers, the requirement for data storage is a routine aspect of development. 

Insecure data storage occurs when sensitive information, such as usernames, passwords, tokens, or financial data, is stored on a device without adequate protection. 

Attackers with physical access, malware running on the device, or even compromised third-party libraries can extract this data. So, it is crucial to recognize the security issues that arise from this practice. 

Key risks include:

  • Plaintext storage of sensitive values.
  • Lack of encryption or reliance on weak ciphers.
  • Misconfigured or overexposed databases.
  • Logs containing sensitive debug or runtime information.
  • Weak key management practices.
  • Residual data left in keyboard caches or backups.

The underlying issue is often not the platform but implementation errors and shortcuts taken during development.

Common insecure data storage risks

On Android, this problem shows up when:

  • Developers rely on default storage without adding encryption.
  • Session tokens or passwords are stored in plaintext for convenience.
  • APIs allow debug builds to leak sensitive state into logs.
  • Local databases remain unencrypted or poorly configured.

Attackers exploit these missteps using reverse engineering, root access, or malware injection. The result: compromised accounts, fraud, and regulatory non-compliance.

SharedPreferences: Plaintext storage risks

SharedPreferences is a simple and efficient API in Android that enables developers to persistently store key-value pairs of basic data types, such as strings, integers, and booleans. 

This API is frequently utilized to save user preferences, application configurations, or small quantities of sensitive information, including session tokens, in the preferred file. An XML file with this name is created (if required) within the device’s /data/data/{package name}/shared_prefs folder. 

By default, data stored in SharedPreferences is saved in an XML file in plain text. If sensitive data, such as API keys, session tokens, or even passwords, is stored in SharedPreferences without encryption, this data can be easily extracted using tools like adb or file explorers. 

Furthermore, using insecure modes like MODE_WORLD_READABLE can expose app data to other apps, leading to data breaches.

 

Secure approach

Use EncryptedSharedPreferences (available in AndroidX Security Library) and avoid storing long-lived secrets altogether.

Android backups: A hidden data exposure point

The android:allowBackup attribute specifies whether a user with USB debugging enabled can back up and restore application data. 

When this flag is true in the AndroidManifest.xml file, it permits any individual with ADB access to create a complete backup of the application data, regardless of whether the device has been rooted.

  • Any sensitive data stored in SharedPreferences, databases, or internal storage could be extracted.
  • Attackers with physical or remote ADB access can retrieve sensitive data without special privileges.
  • If users connect their devices to an untrusted computer, malicious software could exploit this setting to siphon data.

Secure approach

Explicitly exclude sensitive data in AndroidManifest.xml using <fullBackupContent> and apply encryption before storage.

Keystore: Secure by design, risky in practice

The Android Keystore is built to keep your cryptographic keys locked down, making it tough for attackers to extract them from the device.

  • Keys are stored securely and can’t be exported, even if an attacker gains access.
  • You can set rules like requiring user authentication or restricting what each key can do.
  • Trusted hardware (like TEE or StrongBox) adds another layer of protection. When available, make sure to use it.
  • Some developers bypass the Keystore, instead storing API keys or credentials in SharedPreferences, SQLite, or plain text files. These are easy targets for attackers.
  • Using weak, hardcoded, or reused keys puts sensitive data at risk.
  • Storing keys in logs (or exposing them in logcat) can leak secrets unintentionally.
  • On unsupported devices, falling back to software-only storage is less secure.
 

Secure approach

Always store cryptographic keys in the Android Keystore, enable hardware-backed storage when possible, never hardcode secrets, and avoid leaking keys in logs or unsecured files.

Logging pitfalls: How debug data leaks sensitive information

Logging plays a vital role in the debugging and monitoring of applications.

However, inadequate logging practices can lead to the exposure of sensitive information and the creation of security vulnerabilities. 

If attackers gain access to log files or Logcat, they may extract sensitive user details, which could include confidential paths, API keys, or database queries. This situation poses significant risks to users, particularly on rooted devices or during debugging sessions. 

Activating logging in a production environment can disclose internal application information, thereby aiding potential attackers in the reverse-engineering process.

Secure approach

Never log sensitive data. Use ProGuard or R8 to strip logging statements from production builds. Audit third-party SDKs for unsafe logging.

Keyboard cache exposure: Data at risk through input fields

Keyboard caching is designed to enhance the user experience by making typing faster and more convenient. The keyboard cache typically stores frequently used words, phrases, and personal data like contact names or email addresses.

 

What’s the risk?

Android Keyboard Cache Exposure represents a potential security risk, wherein sensitive data entered by users on their Android devices is temporarily stored in the keyboard's cache. 

This information can be accessed by malicious applications or attackers, potentially disclosing private information such as passwords, credit card details, or personal messages due to inadequate data management by the keyboard application

Secure approach

For sensitive input fields, set android:importantForAutofill="no" and android:inputType="textNoSuggestions|textPassword". This prevents caching and autofill leaks.

SQLite databases: The encryption gap in android apps

SQLite serves as a compact database engine frequently utilized in Android devices for data storage. 

However, it is important to note that SQLite does not provide an inherent encryption feature, resulting in all data being stored in cleartext. This situation poses a significant risk, particularly when sensitive information such as credentials, authentication tokens, or personally identifiable information (PII) is stored directly within a SQLite database. 

Such data may be accessible to any process or user on rooted devices, or it could be exposed through a series of vulnerabilities, including unauthorized access to private storage via exposed components.

 

Secure approach

Use SQLCipher or Room with encryption enabled. Apply proper key management and rotate keys when needed.

Realm databases: Security depends on encryption and key management

Realm databases are increasingly favored by developers. The database and its data can be secured through encryption, utilizing a key that is kept in the configuration file. Like SQLite, these databases can also be stored without encryption, allowing for straightforward access. 

The ability to access data is contingent upon its encryption status of the databases. The ones that are not encrypted can be readily accessed, whereas those that are encrypted necessitate an examination of the key management practices. This includes determining whether the key is hardcoded or stored in an insecure manner, such as in shared preferences, or securely within the platform's KeyStore, which is considered the best practice.

Nonetheless, if an attacker gains substantial access to the device, such as through root access, or can repackage the application, they may still extract encryption keys during runtime by utilizing tools like Frida.

Secure approach

Always enable Realm’s built-in encryption, and derive keys securely at runtime using Android Keystore. Never hardcode encryption keys.

Firebase misconfigurations: Open doors to sensitive data

Application developers can leverage the Firebase Real-Time Database to store and sync data with a NoSQL cloud-hosted database. The data is stored as JSON and is synchronized in real-time with every connected client. It also remains available even when the application goes offline.

If a Firebase Realtime Database or Firestore is misconfigured with open read/write permissions, attackers can access or modify data. A misconfigured Firebase database can be accessed using the following URL.

https://_firebaseProjectName_.firebaseio.com/.json

This requires the Firebase project name, which can be accessed through reverse engineering an Android application, reviewing the manifest, or looking through files within the data directory.

Secure approach

Apply strict Firebase security rules. Regularly audit read/write permissions. Never store high-value secrets in Firebase without strong encryption.

Best practices to secure local data storage in Android apps

To prevent insecure data storage, Android developers should:

  • Utilize SQLCipher or similar libraries to add encryption capabilities to SQLite. Alternatively, sensitive data can be encrypted using cryptographically secure algorithms before being stored in the database.
  • Use the EncryptedSharedPreferences class from the “androidx.security:security-crypto“ library to store sensitive data securely. This class encrypts the data before storing it in SharedPreferences.
  • Utilize the Android Keystore system to store cryptographic keys securely. The Keystore ensures that keys are stored in a hardware-backed secure environment, making it difficult for attackers to extract them.
  •  In the AndroidManifest.xml file, set the android:allowBackup attribute to false for applications that handle sensitive data. This prevents unauthorized backups of the app's data via ADB or other means.
  • Ensure that sensitive information, such as passwords, API keys, or personal data, is not logged. Use logging levels appropriately and disable verbose logging in production builds.

Security requires a defense-in-depth mindset. No single control is enough.

Closing the gaps: Building resilient Android apps with secure storage

Insecure local storage remains one of the most critical vulnerabilities in mobile applications, exposing sensitive user data to potential breaches. 

While these storage solutions offer convenience and performance benefits, they require careful consideration of security measures, including robust encryption, strict access controls, and secure authentication protocols. Because the consequences are severe: 

  • Account takeovers, 
  • Fraud, 
  • Data breaches, 
  • Regulatory violations and 
  • Reputational loss.

These risks aren’t hypothetical; attackers actively exploit them. 

By prioritizing secure storage practices, developers not only protect against data breaches but also maintain regulatory compliance and strengthen user confidence. Investing in proper security implementation ultimately leads to more resilient and trustworthy applications that can withstand modern security challenges.