Provider component security in Android security development

Time:2020-10-26

Author: Yiqiao, Daihu @ aliju security

1 Introduction to content provider components

Content provider component is one of the important components of Android applications. It manages data access and is mainly used for data sharing among different applications. The data source of content provider includes not only SQLite database, but also file data. By separating the data storage layer from the application layer, content provider provides a common interface for various data sources.
Provider component security in Android security development

To create a content provider of your own, you need to inherit from the abstract class of ContentProvider, and you need to override the six abstract methods, oncreate(), query(), insert(), update(), delete(), gettype(). These methods can add, delete, modify and query the underlying data source. It is also necessary to register the content provider in the androidmanifest file, and specify the access rights, exported properties, authority property values, etc.
Provider component security in Android security development

Other apps use the contentresolver object to query and operate the content provider, which has a method name with the same name in the content provider. In this way, other apps can access the underlying data of the data source corresponding to the content provider without knowing the data structure or implementation.
How to locate specific data?
Using content URI, a content URI is as follows:

content://com.jaq.providertest.friendsprovider/friends

Its composition is generally divided into three parts
1) Content: / /: as a special ID of content URI (required);
2) Authority: used to uniquely identify the content provider according to which external visitors can find it; in Android manifest, there are;
3) Path: the path to access the data required, depending on the business.

These contents will not be discussed in detail, see reference 1 for details.

2 risk profile

If the exported property of a content provider is set to true in the androidmanifest file, there is one more attack point to attack the app. If there is a problem with the implementation of this content provider, there may be risks such as arbitrary data access, SQL injection, directory traversal, etc.

2.1 wrong definition of private rights results in arbitrary access of data

The risk of private permission definition is that the private permission is defined, but the level of private permission is not defined at all, or the defined permission level is not enough. As a result, malicious applications can access the data provided by the corresponding content provider as long as the permission is declared, resulting in data disclosure.

Take the open black cloud vulnerability wooyun-2014-57590 as an example:
A network disk client uses its own private permission, but there is no private permission defined in Android manifest. Other apps can access the provider provided by this network disk client and access user data as long as they declare this permission.
When registering the provider in the Android manifest of the network disk client, the read-write permissions required for accessing are declared, and the permissions are the private permissions defined by the client:
Provider component security in Android security development

However, there is no private permission in Android manifest“ com.huawei.dbank .v7. provider.DBank.READ_ Database “and“ com.huawei.dbank .v7. provider.DBank.WRITE_ Definition of “database”
Provider component security in Android security development

After decompiling the URIs viewed by the client, the URI accessing the provider can be constructed according to these URIs:
Provider component security in Android security development

Write POC
Take viewing the list of files downloaded from the network disk as an example,
Declare private rights in androidmanifest of POC, and the protection level of permissions is defined as the lowest level “normal”:
Provider component security in Android security development

The main codes are:
Provider component security in Android security development

Get the download list data saved in the database:
Provider component security in Android security development

Corresponding database:
Provider component security in Android security development

In this way, any malicious application can access the user’s online disk upload and download records, the file list stored in the network disk and other privacy information.

Take the open black cloud vulnerability wooyun-2013-039697 as an example

Private permissions are defined, but the protection level is set to dangerous or normal. This protection level is less important than the protection level for some applications.
The provider is:
Provider component security in Android security development

Private rights“ com.renren.mobile . android.permission.PERMISSION_ ADD_ “Account” is defined as:
Provider component security in Android security development

Decompile the client and see the corresponding implementation of acountprovider
Provider component security in Android security development

Write POC:
Define and declare permissions in androidmanifest:
Provider component security in Android security development

The main codes are:
Provider component security in Android security development

You can see the user’s account information, including uid, mobile phone number, encrypted password, etc
Provider component security in Android security development

2.2 local SQL injection

When the data source of content provider is SQLite database, if it is not implemented properly and the provider is exposed, it may cause local SQL injection vulnerability.
The method definition of query() of content provider is as follows:
Provider component security in Android security development

The parameters are as follows:

Uri: content URI, the database to be queried
Projection: is the name of the column to be queried
Selection and selectionargs: to specify the query criteria
Sortorder: how to sort the query results

The comparison between query() and SQL query is as follows:
Provider component security in Android security development

If the SQL statement composed of concatenated strings is used in query () to query the underlying SQLite database, SQL injection is easy to occur.

Take wuyun-2016-0175294 as an example
Client‘s com.sohu.sohuvideo . provider.PlayHistoryProvider The exported property of is “true”:
Provider component security in Android security development

Decompile the client and trace the implementation of playhistoryprovider. It is found that the original SQL query statement is constructed in the form of concatenated strings
Provider component security in Android security development

Use the drozer tool to prove the vulnerability:
Provider component security in Android security development

2.3 directory traversal vulnerability

The exposed content provider implements the openfile() interface, so other applications with the corresponding permission to call the content provider can call the openfile() interface of the content provider for file data access. However, if there is no content provider access control and the URI of the target file to be accessed, the attacker can access any readable file by traversing the file directory, or even write arbitrary data to the writable directory of the mobile phone device.

Example 1: take wuyun-2013-044407 as an example:
In this app implementation, a content provider component that can access local files is defined com.ganji.android . jobs.html5 . localfilecontentprovider is used because minsdkservison is “8” and targetsdkversion is “13”, that is to say, the content provider adopts the default export configuration, that is android:exported= ”true”:
Provider component security in Android security development

The provider implements the openfile() interface
Provider component security in Android security development

The internal storage app can be accessed through this interface_ For the data under the WebView directory, because the background fails to effectively judge the address of the target file, you can traverse the directory through “.” / “, and access any private data.

Example 2
A social application client uses minsdkversion of 8, defines private permissions, and android:protectionLevel Set to signature
Provider component security in Android security development

There is an exposed content provider, that is com.facebook.lite . photo.MediaContentProvider , this provider does not have access rights set, and the other provider has access rights set:
Provider component security in Android security development

The openfile() interface is implemented in mediacontentprovider, and the incoming URI is not restricted and filtered
Provider component security in Android security development

This interface only wants to let users access photo information, but it can break through the restrictions and read other files
POC:
Provider component security in Android security development

Read the contents of other files as follows:
Provider component security in Android security development

In addition, we can see that in the implementation of openFile () interface, if the file to be accessed does not exist, this file will be created. There is also a possible risk of writing arbitrary files in the application directory.

3. Suggestions of aliju security developers

When designing an app, it is necessary to know which provider’s data are user’s private data or other important data, and consider whether to provide it to external applications. If not, set the exported attribute to “false” in the Android manifest file, which will reduce a large part of the attack area.
Manual troubleshooting is certainly troublesome. It is recommended that developers use the security scanning service provided by aliju security to conduct automatic security scanning before the app goes online, so as to discover and avoid such risks as soon as possible.

be careful:
It is not recommended that the Android SDK version 2 (content level 2) should not be set to the lowest version of SDK (8) for several years, so it is not recommended that the Android SDK version should be higher than 8;
Since API level is below 17, all applications“ android:exported ”The default value of the property is true. Therefore, if the applied content provider does not need to be exported, it is recommended to explicitly set the“ android:exported ”The attribute is false;
If it is necessary to provide data to external applications, we should do a good job in design and permission control, and make clear what kind of external applications can be used. For example, the same signature can be used for the company’s application when defining the permission, and the partner’s application can check its signature. However, it is still not necessary to provide user’s privacy sensitive information.

For providers that must be exposed, such as the risks encountered in the second part, the solutions are as follows:

3.1 define private permissions correctly

The syntax for defining private permissions in androidmanifest is as follows:
Provider component security in Android security development

among android:protectionLevel The optional values of are as follows:

  • Normal: the default value is low-risk permissions. During installation, the system will automatically grant permissions to application.

  • Dangerous: high risk permissions, such as texting, calling, reading and writing address book. Use this protectionlevel to identify some of the permissions that users may be interested in. Android will alert users about these permissions when installing the program. The specific behavior may vary according to the Android version or the installed mobile device.

  • Signature: Signature permission. When other apps refer to the declared permissions, the signatures of the two apps need to be consistent. In this way, the system will automatically grant permissions to third parties

  • App without prompting the user. Signatureorsystem: in addition to apps with the same signature, programs in Android system have access rights.

Most of the open providers are provided to other applications of the company. Generally speaking, the signature certificates of a company’s packaged signature app should be consistent. In this case, the android:protectionLevel Should be set to ‘signature’.

3.2 prevent local SQL injection

Note: never use splicing to assemble SQL statements.
If the data source of content provider is SQLite database, SQL injection will be caused if the original SQL statement is executed in the form of concatenated strings.
The following selection clause:
Provider component security in Android security development

If you do this, the user will be allowed to concatenate malicious SQL to SQL statements.
For example, a user can enter “nothing; drop table * *;” for muserinput, which generates a selection clause

var = nothing; DROP TABLE **;

Since the selection clause is processed as an SQL statement, this may cause the provider to erase the underlying SQLite database
Unless the provider is set to capture SQL injection attempts.

Use parameterized query:
To avoid this problem, use a “?” as a selection clause for replaceable parameters and a separate array of selection parameters.
When you do this, user input is directly constrained by the query and is not interpreted as part of the SQL statement.
Unable to inject malicious SQL because user input is not processed as SQL.

Use this selection clause instead of concatenation to include user input:

String mSelectionClause = “var = ?”;

Set the selection parameter array as follows:

String[] selectionArgs = {“”};

Place the values in the selection parameter array as follows:

selectionArgs[0] = mUserInput;

You can also call the parameterized query() method in the sqlitedatabase class:
Provider component security in Android security development

3.3 prevent directory traversal

1. Remove the unnecessary openfile() interface from the content provider.
2. Filtering restricts cross domain access and effectively judges the path of the target file to be accessed
use Uri.decode () decode the content query URI first, and then filter the URI string that can access any readable file through “…”, such as:
Provider component security in Android security development

3.4 authorization of partner application access by detecting signature
If the partner’s app must be provided with provider access rights, and the partner’s app signature certificate is different from that of its own company, the signature hash value of the partner’s app can be embedded in the provider’s app. The provider’s app needs to check the signature of the app requesting access to this provider, and access is allowed only when the signature matches.

reference resources

[1] Content provider Basics
》 https://developer.android.com/guide/topics/providers/content-provider-basics.html
[2] SQL Injection on Android App http://zone.wooyun.org/content/15097
[3]《Android – Content Providers》 http://www.tutorialspoint.com/android/android_content_providers.htm
[4] http://www.compiletimeerror.com/2013/12/content-provider-in-android.html
[5] https://developer.android.com/guide/topics/manifest/permission-element.html?hl=zh-cn
[6] https://developer.android.com/guide/topics/manifest/permission-element.html
[7] http://www.wooyun.org/bugs/wooyun-2013-039697
[8] http://www.wooyun.org/bugs/wooyun-2014-057590
[9] 《Android Content Provider Security》http://drops.wooyun.org/tips/4314
[10] http://www.wooyun.org/bugs/wooyun-2016-0175294
[11]《Android Content Provider Security
》http://drops.wooyun.org/tips/4314
[12] http://www.wooyun.org/bugs/wooyun-2013-044407
[13] http://www.wooyun.org/bugs/wooyun-2013-044411
[14] Analysis of loopholes in content provider file directory traversal, https://jaq.alibaba.com/blog.htm?id=61
[15] https://github.com/programa-stic/security-advisories/tree/master/FacebookLite

Author: Yiqiao, Daihu @ aliju security, for more security technical articles, please visit aliju security blog