You can read Part Two of this series here.
This is the scene; on one side, we have the Android platform developers and on the other, the hackers. Just as with any software system, Android has its list of security problems. And it’s a pretty close race between the two sides.
In spite of the world’s most accomplished security professionals working on the Android platform’s, there have been cases where a user should not have ‘trusted’ the released application.
The flexible platform works on heavy collaborations between applications and dependencies can range from simple to complex. In this scenario, the dependencies are bound to be exploited to acquire data, passwords, and eventually control over the application.
In this article, I share my learning around security measures developers must take into consideration to avoid introducing vulnerabilities in our Android apps. Let's look at a typical Android application. On studying the diagram, if asked to list down the components that could leak some kind of data or capabilities from Android, what would be the answer?
Every single component!
Yes, every component could be exposing data if we are not taking the necessary precautions.
- The activities could be leaking personal data to the log file.
- The service could remote calls from other apps that don't have permission.
- The settings file could be world readable or world writable allowing access to the service. For example, an application requires the user’s location for a feature. As needed for a temporary purpose,the developer stores the location obtained in a world readable file and boom - another app can access the location without requesting the appropriate permissions. The effectiveness of the permission model is removed.
- The content provider could be granting access to the database.
- The data being transmitted over the network could be in clear text or the web service itself could be compromised.
I am sure, you say, the Android permission model is in place and therefore we should not have to be so scared. Yes, it's often easier to write a secure app in Android than it is to write an insecure app but only if one knows what's safe and what’s not safe.
In this first post in the series, I share some dos and don’ts and a few tools to help one develop a secure app.
Be careful while dealing with intent-filters.
Requirement: Need to start the same service for two different jobs.
Implementation: Code can be found here. Say this is App1.
- App1 does two simple things: Uploads data and Downloads data.
- Now if you checkout this malicious app and run it, you will observe that it can download data via the App1.
- As the malicious app knew the "action" to trigger the service and as the service was started via an implicit intent, the App1 allowed the malicious app to download data on it’s behalf.
To understand the difference between explicit and implicit intents, read - https://developer.android.com/guide/components/intents-filters.html#Types
How to avoid this?
Because an intent filter signals to the Android system that you want these components exposed to other apps, it’s a good idea to make an explicit decision whether to mark a component as exported. Android doesn’t require you to do so, but as you see, there are security repercussions to not doing so.
If you choose to set the value of “exported” = “false” in your intent filter definition, you can prevent accidentally exporting internal components.
In the AndroidManifest.xml
Think about it - If you didn't intent a component to be exported in your app and maybe some months later you or a colleague adds an intent filter for something they need, they might inadvertently export that component and it could cause a security vulnerability later.
Note: If you do wish to make your components available but only for limited use, there are permissions you can grant in the AndroidManifest.XML.
The above solution will help solve the Confused Deputy Problem.
What is a Confused Deputy Problem?
Let's take an example:
Android OS has a Wi-Fi manager which is inside the system server. Now our app has a service that talks to the Wi-Fi manager.
Confused Deputy Problem Scenario 1:
- Our app asks the Wi-Fi manager, whether it's allowed to access Wi-Fi
- Our app would be granted the permission as it requested for the appropriate Wi-Fi permission during installation.
- If an attacker app that requests no such permission is installed and it asked the Wi-Fi manager, it would be denied.
But what happens if your app is exposing a component (say through an exposed intent-filter) that is part of the Wi-Fi control and the attacker decides that it can ask your app?
Confused Deputy Problem Scenario 2:
- Our app might be asked by the attacker app to access WiFi
- Our app would ask the Wi-Fi manager and it would grant the attacker app the permission because our app had asked for the permission during installation.
- Our app could return some information back to the attacker app without having the correct permission and our app has become the confused deputy.
It is being “deputized” by the Wi-Fi manager and it has leaked information to the other app without the correct permission.
You can avoid your app from being deputized by a malicious app by:
- Explicitly mark components as exported.
- Granting appropriate permissions in the manifest file.
Here is a webinar done by me on this topic:
Look for my next post around vulnerabilities that can be added while sending a broadcast, how to minimize permissions to make your apps secure and a few tools to help you keep your Android apps secure.