These days, developing secure Android applications is more important than ever before.
Android now commands 76% of the smartphone market in the EU5¹, 67% in the US and nearly 80% in China, according to latest figures².
With numbers like that, it’s no wonder the Android application development gold rush is continuing; nearly a quarter of a million apps have been added to Google Play so far in 2016³.
That’s an average of 1,379 apps every day!
However, with Accessibility Clickjacking, Stagefright, Triada and other malware among the growing list of Android exploits, developers simply cannot afford to place security anywhere other than at top of the priority list.
With that in mind, in this article we’re taking a look at some best practice tips for developing secure Android applications.
The .apk Format for Android Applications
Android applications exist in an apk format on devices with they are installed. These apk files are similar to zip files, they just have a different extension, renaming the apk to a zip file you can access everything inside that is needed to run. The APK can be easily pulled from a phone using a file manager or ADB (Android Debugging Bridge) to transfer it directly to your computer.
These apk files can be easily reverse-engineered turning back into Java source code. If the application was not obfuscated, this would allow easy access to the original algorithms, embedded URLs and passwords. The source code could then be modified and the application rebuilt – resulting in changes from circumventing licensing checks, changing the program flow to other more malicious actions.
Below we will examine some of the protocols followed to help keep information safe from prying eyes. They are:
- Obfuscating your strings
- Obfuscating your code
- Validating your apk
- Using HTTPS and SSLSocket
- Saving data with encryption
Developing Secure Android Applications – 5 Tips
1. Obfuscate Your Strings
Probably one of the most obvious steps is obfuscating sensitive strings. Once someone has the de-compiled source code, it’s easy to trawl through the resulting Java to find important strings. These strings can include website URLs, default passwords, certificates and predefined communications protocols (which are quite nice if you want to try injecting some of your own data).
Fig.1: Server address decompiled in plain text.
To protect against this, there are different levels of obfuscation that can be implemented, each with a higher level of complexity to write each time. Additionally, you can throw in `dummy` strings into your code with the idea of once again making it harder to determine what is relevant.
Simple: Store strings as arrays of bytes or Base64 encode the strings. Android has a utility method for this:
Fig.2: Android’s base 64 encode utility method.
Advanced: Encrypting the strings. This can be achieved by using a secure encryption algorithm such as AES; though it is important to be careful how you store the encryption key, using the Android keystore is recommended. If your application has access to online features you can also use these to check permissions and access to app features.
Fig.3 Decompiled server address after encryption.
2. Obfuscate Your Code
Code obfuscation – like string obfuscation – is about making the code harder to reverse engineer. Android build systems come with a tool called ProGuard. When configured, this will obfuscate your code as well as optimizing and shrinking it. The way it does this is by renaming classes, methods and fields to identifiers that have no semantic meaning.
Fig.4: Proguard mapping output
In this case, after ProGuard has completed its pass-through, if the resulting apk is de-compiled, any calls to access the m_serverIpObfuscated variable f1878a.
This helps to obscure the meaning behind the code without having to worry about naming conventions disclosing their functionality.
Fig.5: Decompiled sources with obfuscated code classes/methods/fields and encrypted strings
3. Validate Your APK
Once someone has reverse-engineered application code they can make malicious changes to it, re-compile and upload it to package repositories.
To protect against this within the application it is advised to self-validate at start-up and before performing any sensitive tasks. In the case self-validation is a collection of checks to ensure the configuration of the APK is as expected.
Ensure debugging flags are off. In a release application if debugging flags are enabled then it is possible to debug through an IDE and stepping through code and identifying variable values.
Fig.6: Example code for checking debug flags of an apk
Verify the package signature. Every android application has to be signed with a key; this should only be known by the developer/company behind the application. As a result we can compare the key we have for our keystore compared to the key that was used to sign the application.
To achieve this, store an encrypted version of the key (SHA -256 hash/digest of the certificate) within the application. When this is to be checked retrieve the current package signature SHA-256, hash it, encrypt and compare to the stored value.
4. Always Use HTTPS and SSLSocket
Where supported by a server, HTTPS should always be used over HTTP especially when handling sensitive data, such as personal user data or external IOT device commands.
Mobiles users connect to many different public Wi-Fi hotspots which could contain rogue individuals with IP packet sniffers such as Wireshark. Data downloaded through HTTP connections should be approached cautiously as it could be tampered with malicious intent.
For these reasons, SSLSockets are also preferred over standard Sockets. They provide authentication with the end point as well as encryption of data using the transport protocol. Developers can check and verify the certificate of the server they are trying to connect to against a hash of what it should be; this prevents DNS alteration attacks where someone is routing traffic to a dummy site on a public access point.
5. Encrypt Your Save Data
Most of the data stored by an application is within the applications sandbox and is safe from other apps, including Android’s Shared Preferences. However, this is not true for rooted devices, for which, access to usually restricted application space is granted. This – and unsecured, re-compiled applications – is why storing data as plain text is a big no-no.
If sensitive data does need to be stored then it should be sufficiently encrypted (AES). If passwords are required as part of the application locally, it’s better to store a hash and compare the resulting value against the result of hashing the new password.
For server communications that require password authentication, the first transaction should be to use a secure hashing function on the password (SHA-256) with the result to act as the password. This is then sent and stored on the server and any further authentication attempts compare the two hashes.
This approach is focused on protecting the users’ data. If there is a compromise on the server, the users’ passwords are not stored; it is just a hash, and without the shared secret they cannot match an input to an output. No personal or sensitive data should be stored as plain text.
What are your tips for developing secure Android applications? Connect with us and let us know via our social media channels – it’d be great to hear from you!
Android Fast Facts in Numbers
7 Years Since 1st widely commercially available release of Android OS – April 2009
1.4 billion Number of Android users worldwide
84% Android’s global market share4
8 in 10 (87.7%) of Android devices exposed to 1 of 11 known critical exploits5
97% of all mobile malware is targeted at Android
1 billion Number of users affected by Stagefright, the worst ever Android exploit
11 Different names for Android OS (as of 30/06/16): Cupcake, Donut, Éclair, Froyo, Gingerbread, Honeycomb, Ice-Cream Sandwich, Jellybean, Kit Kat, Marshmallow
7 OS versions. The latest, dubbed Android N, was released in March 2016.
Unveiled as Android Nougat by Google in June 2016 after a worldwide public vote
Notes & Further Reading
¹EU5 countries are Germany, Great Britain, France, Italy, and Spain
²Kantor World Panel
³Appbrain (figure excludes low quality apps)
Android Security Bulletin
Android Application Development Services
*Title & 1st article images by Scott @ norebbo.com*