In the previous article, we discussed Content provider leakage how an attacker exploits vulnerable activity components and ways to secure them. In this article, we will cover Content provider leakage”.
What are Content provider leakage?
According to Google’s built-in security model, app data is private to the app, so it’s impossible for an app to access another app’s data by default. When applications want to share their data with other applications, a Content Provider is a way that acts as an interface to share data between applications. Content providers use the standard insert(), query(), update(), and delete() methods to access application data. Each content provider is assigned a special form of URI that begins with “content://”. Any application that knows this URI can insert, update, delete, and query data from the provider application’s database.
There may be cases where content providers may not be implemented to share data with other applications, or the developer may want to grant access only to those applications that have the correct permissions. In such cases, if proper security controls are not enforced in the application, it leads to information leakage.
The built-in SMS application on Android devices is a classic example of content providers. Any application can query the device’s inbox using its URI
content://sms/inbox. However, in order to access SMS application data, the READ_SMS permission must be declared in the application’s AndroidManifest.xml file.
You can download the sample application used in this article.
Prerequisites for performing the steps
- A computer with the Android SDK installed
- A non-rooted mobile device to install the app
Testing the functionality of the application
After downloading the test app, install it on your non-rooted Android device to test and use it.
It can be installed using adb using the following command:
adb install .apk
It has a function to store data inside the application. When we run it, it will appear as in the picture.
The goal is to find out if there are any content providers implemented in this application, and if YES, we need to check and exploit if they are vulnerable to data leakage.
- Collection of information
- Attacking vulnerable content providers
- Application security
Collection of information
Like any other pentest, let’s start by gathering information. We assume that we have the APK file with us. So, decompile the downloaded APK file as mentioned in part 1 and check the AndroidManifest.xml file for registered content providers. We should also check small files for all URIs used in the application.
Content providers are generally registered in the AndroidManifest.xml file in the following format.
So let’s go ahead and explore the manifest file.
We have one content provider registered in the AndroidManifest.xml file and the good news is that it is exported so that all other applications can access it.
Attacking vulnerable content providers
This is the most interesting part. Now let’s try asking the content provider we found. If it returns any data, then it is vulnerable. This can be done in several ways.
- Using the adb environment
- Using a malicious application to query
- Using the Mercury Framework
To query content providers from adb, the app should be installed on the device.
Get an adb shell on your device and type the following command to query the content provider. In my case, I ask for the URI that I found in the MyProvider.smali file that is extracted by the APK tool.
Content –query –uri content://com.isi.contentprovider.MyProvider/udetails
Now we should see all the details stored in the application db as shown in the image below.
Using a malicious application to query
We can even write a malicious application that queries its content provider for data. The following is a code snippet for querying the inbox from a mobile device.
Using the Mercury Framework
The whole process can be done even more efficiently and easily with Mercury Framework.
- Setting the value of the android:exported attribute to false:
In our app’s AndroidManifest.xml file, we should add the following attribute to the content provider to be secure. In our case, the content provider is com.isi.contentprovider.MyProvider.
If we try to query a content provider whose android:exported value is set to false, it will throw an exception as shown below.
Note: The default value of android:exported applies to all apps using an API level lower than 17.
- Restrict access using custom permissions
We can also impose permission-based restrictions by defining custom permissions for the activity. This is useful if a developer wants to restrict access to their application’s components to applications that have permissions.
Other issues with content providers
SQL Injection: If security controls are not properly implemented, content providers can lead to client-side attacks such as SQL injection. It works similarly to traditional SQL injection attacks.