Smartphones are treasure troves of personal data. A typical smartphone may contain these sensitive data:
- Whom its owner calls, email, SMS with and how often.
- Location history (gathered by GPS or other methods).
- The owner’s personal and business calendars.
- Login credentials (e.g. email, Twitter, Facebook, VPN, and websites).
- Photos and videos.
Security firm F-secure reports that Android malware has quadrupled in 2012 compared to a year ago. With mobile payment and banking on the rise, criminals have increased financial incentives to attack mobile devices. It is no surprise mobile has become a lucrative targets for criminals.
While no mobile platform is immune from malware, Android’s relatively open and extensive API results in unique security challenges for app developers; even Google’s engineers inadvertently introduced serious security bugs in their apps: http://money.cnn.com/2011/05/18/technology/android_security/?section=money_latest.
In this article, I will share engineering tips to harden an Android app.
Top Android Secure Coding Practices and Pitfalls to Avoid
- When creating files, use MODE_PRIVATE. Avoid MODE_WORLD_READABLE (potential data leak), or MODE_WORLD_WRITABLE (allowing an adversary to flood the device memory while masquerading as your app).
- Don’t write sensitive data to public places (e.g. sd card or a public Content Provider).
- Don’t write sensitive data (e.g. password or tokens) to the logcat. logcat is a globally readable area.
- Avoid loading dex class files over the network or from any public locations such as sd card. It is possible for an adversary to inject arbitrary code into your app.
- Defend against SQL Injection: Use parameterized database queries rather than building SQL statements dynamically using string concatenation. Make your selection strings final to prevent them from being changed by an adversary.
- Don’t make your application component (e.g. Service or Content Providers) accessible to third party apps unless you really mean to. Remember to set android:exported=false.
- For any public API that your app exposes (e.g. Service, Broadcast Receiver, Activity etc), ensure your app validates against each input argument; check each argument conforms to your expectation. Never assume that the data your app receives is well formed or valid. Malicious users will try every sort of malformed input to see what effect it has on your app. Don’t design an API that accept arbitrary path name or a server address; this could enable a malicious app to redirect your app into sending/receiving data to a location of the hacker’s choosing.
- Don’t expose privileged system APIs (e.g. send SMS) or sensitive user data (e.g. call logs, device locations) via your public API unless the caller app has been granted the appropriate permissions. Always assume a malicious app (with possibly no permission) will take advantage of your public API to gain privileged access. Use PendingIntent instead of Intent to prevent a malicious API caller from tricking your app into performing a privileged action. Android Notification and AlarmManager API are great examples for using PendingIntent.
- Don’t transmit sensitive data unencrypted. Use TLS / HTTPS.
- Never include any sort of secret key in code. For example, if your app uses a symmetric key to encrypt data, don’t include the key in code. It is straightforward for an adversary to de-compile byte code to extract the key.
- Do not declare unneeded permission in the app manifest file. Although this won’t make your app more secure, excessive permissions is one source of negative user ratings.
- Be transparent to your users: Let them decide if and when potentially sensitive data (e.g. location, address book, or call logs) are sent.
- Run static analysis tools to catch potential coding errors and security issues.
- Use ProGuard to obfuscate your code to make reverse engineering of your codebase more difficult.
- Make building secure products a part of your corporate engineering culture. (e.g. establish a peer code review process.)
The above list is by no means exhaustive; obviously, there are other attack vectors I am not aware of. Please comment if you have additional tips to share.
Android has a technically sound security model. However, the overall security of the device is only as strong as its weakest link; it only takes a single insecure app to expose all of the user’s private data on the device (or worse). Android app developers must recognize that writing secure complex apps takes effort and should keep secure coding habits in mind.
I predict security threats against mobile devices will continue to increase (in number and sophistication) in the next 12 months. It is more important than ever to make security a priority and follow secure coding practices.