This rule is deprecated, and will eventually be removed.

Android components that are exported can be used by other applications. This may give access to functionalities that should remain private.

Why is this an issue?

Once an Android component has been exported, it can be used by attackers to launch malicious actions and might also give access to other components that are not exported. For this reason, the following components should be protected:

What is the potential impact?

When components are exported unintentionally, they can be accessed and manipulated by other applications, potentially leading to unauthorized data access, data corruption, or even control over certain functionalities of the application.

Below are some real-world scenarios that illustrate some impacts of an attacker exploiting the vulnerability:

Unauthorized Data Access

If a component that handles sensitive data is exported, other applications can potentially access this data. For instance, if an activity that displays private messages is exported, a malicious application could send an intent to this activity and read the user’s private messages.

Unwanted Control Over Application Functionality

If a broadcast receiver is exported, other applications can send intents to it, triggering it to perform actions. This could lead to unwanted behaviors. For instance, a malicious application could trigger a receiver that starts a certain activity, causing the user’s device to open unwanted screens, consume unnecessary resources, or even perform harmful actions.

How to fix it

Code examples

Noncompliant code example

This sample exports a provider and does not define permissions:

<provider
  android:authorities="com.example.app.Provider"
  android:name="com.example.app.Provider"
  android:exported="true" />  <!-- Noncompliant -->

This sample exports a provider and does not define READ permission:

<provider
  android:authorities="com.example.app.Provider"
  android:name="com.example.app.Provider"
  android:exported="true"
  android:writePermission="com.example.app.WRITE_PERMISSION" />  <!-- Noncompliant -->

This sample exports a provider and does not define permissions:

<activity android:name="com.example.activity.Activity">  <!-- Noncompliant -->
  <intent-filter>
    <action android:name="com.example.OPEN_UI"/>
    <category android:name="android.intent.category.DEFAULT"/>
  </intent-filter>
</activity>

Compliant solution

<provider
  android:authorities="com.example.app.Provider"
  android:name="com.example.app.Provider"
  android:exported="false" />
<provider
  android:authorities="com.example.app.Provider"
  android:name="com.example.app.Provider"
  android:exported="true"
  android:readPermission="com.example.app.READ_PERMISSION"
  android:writePermission="com.example.app.WRITE_PERMISSION" />
<permission android:name="com.example.app.PERMISSION" android:protectionLevel="signature" />

<activity android:name="com.example.activity.Activity"
          android:permission="com.example.app.PERMISSION" >
  <intent-filter>
    <action android:name="com.example.OPEN_UI"/>
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

How does this work?

The preferred way to protect components is to set exported to false. The component is not exported and can only be used by its application.

If the component, such as a provider, has to be exported because it is shared with some other application, add android:readPermission and android:writePermission attributes.

Another way to secure access to components is to create a permission with the <permission> tag and add it to the component with the android:permission attribute.

Pitfalls

When targeting Android API versions lower than 12, intent filters will cause exported to be set to true by default.

Resources

Documentation

Standards

External coding guidelines