Security

    Android content provider security explained

    A 2026 view of an Android content provider exposing structured data to other apps, with SQL injection through a concatenated caller selection and the fix of parameterized queries

    A content provider is how Android apps share structured data, and an exposed one can hand your app's data to other apps, or hand an attacker a way to query data they should not see. Two problems show up: a provider exported when it was meant to be internal, so other apps can read it, and a provider that builds its database queries from caller-supplied input, which opens it to SQL injection from another app. Both are avoidable with the same discipline you apply to any component that accepts external input. Here is what a content provider exposes and how to secure it.

    Short answer

    A content provider shares structured data through a content:// URI, and other apps can query it if it is exported. Per Android's guidance, the risks are exporting a provider that serves internal data, so other apps can read or modify it, and SQL injection when the provider builds its query from caller-supplied input by concatenating it into the selection. The defense is to set android:exported="false" for providers serving private data, and for any provider that must be exported, protect it with permissions, validate the caller's input, and use parameterized queries with selection arguments rather than string concatenation. Treat a content provider that accepts input from other apps as handling untrusted input.

    What you should know

    • Content providers share data via content:// URIs: across apps if exported.
    • An exported provider exposes its data: other apps can query it.
    • Query injection is a risk: concatenating caller input into SQL.
    • Default to non-exported: for providers serving internal data.
    • Use parameterized queries: selection arguments, not string concatenation.

    What is a content provider, and what is the exposure?

    It is a component that exposes a set of data, often backed by a database, to be queried and modified through a content:// URI. When a content provider is exported, other apps can call its query, insert, update, and delete methods, which is the point when you intend to share data, and a problem when you did not. The exposure is twofold: an exported provider serving your app's private data lets other apps reach that data, and a provider that accepts caller input, a selection clause, an identifier, a sort order, and uses it to build a database query can be attacked through that input. Because a content provider sits at the boundary between your app and others, anything it accepts from a caller is untrusted, and anything it exposes is reachable by whoever can call it.

    What are the risks?

    Data exposure and query injection. The table lists them.

    RiskHow it happens
    Exposing internal dataA provider serving private data is exported
    SQL injectionCaller input concatenated into the query selection
    Unrestricted modificationExported provider allows insert, update, or delete by others
    Path or identifier abuseCaller-supplied identifiers reach the data unchecked

    The query-injection risk is the one developers underestimate: if your provider takes a selection string or an identifier from the caller and concatenates it into the SQL it runs, another app can craft input that changes the query, extracting rows it should not see or affecting data it should not touch, the same SQL injection seen on the web but reachable from another app. Combined with an over-exported provider, that turns your data store into something other apps can probe.

    How do you secure a content provider?

    Limit exposure, enforce permissions, and parameterize queries. Set android:exported="false" on any provider that serves data only your app needs, so other apps cannot reach it at all. For a provider you genuinely must expose, protect it with permissions, ideally signature-level so only your own apps can call it, and consider granting temporary URI permissions for specific data rather than broad access. Treat everything the caller supplies as untrusted: validate identifiers and parameters, and build database queries with parameterized selection arguments rather than concatenating caller input into the SQL, which closes the injection path. Restrict which data and operations the provider exposes to the minimum the legitimate use needs. The principle is the same as for any external-facing component: do not expose more than necessary, and never trust caller input in a query.

    What to watch out for

    The first trap is an exported provider serving internal data, which lets other apps read or modify it; set it non-exported. The second is building the provider's query by concatenating a caller-supplied selection or identifier, which is SQL injection from another app; use parameterized selection arguments. The third is exposing insert, update, or delete to callers that should only read, or not at all. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled APK or AAB against OWASP MASVS and surfaces your exported components, including content providers, so you can confirm a provider is not exposing data it should not before you ship. The query handling and permissions you implement in the provider.

    What to take away

    • A content provider shares structured data via a content:// URI, and an exported one lets other apps query or modify it.
    • The risks are exposing internal data through an exported provider and SQL injection when caller input is concatenated into the query.
    • Set android:exported="false" for internal providers, protect any exported one with permissions, validate caller input, and use parameterized selection arguments.
    • Use a pre-submission scan such as PTKD.com to confirm your content providers are not exposing data they should not.
    • #android
    • #content-provider
    • #sql-injection
    • #exported-components
    • #owasp-masvs
    • #app-security
    • #android-manifest

    Frequently asked questions

    What is the risk with an exported content provider?
    An exported content provider lets other apps call its query, insert, update, and delete methods, so a provider serving your app's private data exposes that data to other apps, and one that allows modification lets them change it. That is intended when you mean to share data and a problem when you did not. Because the provider sits at the boundary between your app and others, an exported one is reachable by whoever can call it, so default internal providers to non-exported.
    Can a content provider have SQL injection?
    Yes. If a provider takes a selection clause, an identifier, or a sort order from the caller and concatenates it into the SQL it runs, another app can craft input that changes the query, extracting rows it should not see or affecting data it should not touch. It is the same SQL injection seen on the web, reachable from another app. The fix is to build queries with parameterized selection arguments rather than concatenating caller input into the SQL.
    How do I secure a content provider?
    Set android:exported false on any provider serving data only your app needs, so others cannot reach it. For a provider you must expose, protect it with permissions, ideally signature-level so only your own apps can call it, and consider temporary URI permissions for specific data. Treat caller input as untrusted: validate identifiers and parameters, use parameterized selection arguments instead of string concatenation, and restrict the data and operations exposed to the minimum needed.
    Should my content provider be exported?
    Only if other apps genuinely need to access its data. Default to android:exported false for providers that serve data internal to your app, since exporting one needlessly exposes its data. Export a provider only when sharing the data is the intended feature, and then lock it down with permissions, input validation, parameterized queries, and the least data and operations necessary. The default-private posture prevents the common mistake of leaking app data through an unintentionally exported provider.
    How do I check my content providers?
    Scan the build. A pre-submission scan such as PTKD.com reads the compiled APK or AAB against OWASP MASVS and surfaces your exported components, including content providers, so you can confirm a provider is not exposing data it should not before you ship. If it flags an exported provider serving internal data, the fix is to set it non-exported, and for any provider that must be exported, add permissions, validate input, and use parameterized queries.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free