Android SharedPreferences data weakness
Android SharedPreferences — a common component of Android applications — are a set of APIs that manages for the developer data of every type, providing a clean way to permanently store and retrive them from the device. Them are used almost in every android app.
I think is important to underline that although the simplicity and the apparent security of this platform, after a further analytics we can see a wide range of security flaws, as all the saved values are deliberately readable and editable, from the users or from 3rd-part apps, and this may lead to an unexpected application behavior or, in cases of sensibles data store, them leaks and exploitation
Understanding how SharedPreferences works
We can approach at the SharedPreferences APIs in 2 different methods.
- Reading: the getSharedPreferences() object let the user retrieve informations from the preferences file and to parse them as different types
- Writing: the Editor class (Belongs to SharedPreferences.java) is called and the preferences edits are enqueued. When the applier is called (via apply() or commit()) the values are written on a file and are ready to be read
By written I mean, literally. An XML file is stored in the application internal storage and it’s under ~/shared_prefs/
This means that our values are under the protected /data partition (By default the user cannot even list files over there), under the data directory, under the application specific directory identified by the package name, under the shared_prefs directory.
Let’s suppose that we want to save login username and id to SharedPreferences: first of all we write the following code
After this snippet is executed our file will look like this
And to retrive the values from the file
What is stored into SharedPreferences
SharedPreferences are used to store 3 types of values — Strings, Numbers (Int, Float, Long) and Booleans.
Basing on your application logic, some common values that are usually stored are settings, user purchases, list indexes (We will see them deeply later), A/B testing values, passwords of web services/tokens and more stuff like that. You can understand how critical is the priority to keep this sort of data private to avoid information leaks/misbehavior of your app
How to manipulate SharedPreferences
Let’s suppose that our user doesn’t know a lot about computers and he is ok with this type of APIs, he doesn’t know what SharedPreferences are and how them works. Let’s suppose, on the other hand, that we are in front of an user who knows how machines works and he has all the necessary tools he needs to exploit our application’s preferences and control it as he wants.
As you may see, the xml file contains the preferences values as plain-text, a very clear displaying method, so for the user it won’t be so difficult type the followings lines in the terminal as root. We will take as example com.android.testing
su -c cat *.xml | grep boolean
This code if executed displays every boolean value that the application may store and the actual state. It’s impressive how 2 lines of code can reveal every single field that your application uses to select its appropriate behavior.
To edit this file, he only needs a text editor and basic knowledge of xml. Again, he will have access to everything that is customizable in your application and this is dangerous for example if your app contains pro features and you control their state via SharedPreferences. It’s also dangerous if you store data such as tokens, passwords and usernames because then can be read and used outside of your application. There are specific tools for the android operative system that let users extract, read, edit and apply every single preference file that is in your app in seconds (Like Apkeditor)
I’m not going to provide a full-working proof of concept but it happened so many times to me to do that and every time it was surprisingly easy to get into the app and to modify what I wanted. For example, recently I wanted to install an always-on themes manager and the normal version provided only 2 out of 20 themes. What i did on first thought was obviously get into the shared_prefs directory and try to list the files, i found some of them about Crashlytics (I didn’t care about), and one with the name similar to the package name and the suffix “_settings”. Ka-boom.
I opened it and i could see some names with “settings_” prefix, so them were for the UI and one integer was identified as “selected_watchface”, it was set to 0. Actually I didn’t buy the pro version but all i needed was set this at the watchface number (An index in a list) going from 0 to 19, and the game was done.
Another app that I could exploit was a periodic table app. I could get into the same xml file and there was a property called “pro”, this was too easy
The last trick that i want to share with you was recovering the password of my online school diary account. I opened a file called “auth.xml” and then I could see a JSON string containing last used usernames and password for login, and I managed to recover them
How to protect yourself from these attacks
I adopted this method in all my applications to preserve data integrity and provide a strong security level.
Basically, I have one encryption key that I use to encrypt everything I pass to the shared preferences wrapper. It encrypts both keys and values, and then applies the file modifications. To read is the same. And if somebody open my apps’ xml files he will find a bunch of unreadable stuff. Only some applications have implemented this mechanism, such as 1Password and some Supercell games. (Them also provides advanced database encryption/hashing and masked network operations but this is another level of security).
Also, if you are a developer you can quickly adopt this solution using my library here
Another additional step could be — sorry for the repetition — encrypting the encryption key into the native library, so also with a decompiler your little hacker won’t be able to do anything. There are a few tools that does the work like chiper.so, check them out because it’s very useful
This is my first post on medium, I hope I wasn’t too boring. Clap if you want more articles like that 💪