The android:exported attribute decides whether other apps on the device can reach into your app's components, and getting it wrong is a common, quiet Android security hole. An activity, service, or receiver marked exported can be launched or messaged by any other app, which is fine for a launcher screen and dangerous for an internal screen that assumes only your own code can reach it. Since Android 12 you must set the attribute explicitly, which is a good moment to get it right. Here is what it controls and how to lock it down.
Short answer
android:exported controls whether components in your Android app, such as activities, services, and broadcast receivers, can be invoked by other apps. Per Android's documentation, a component set to exported="true" is reachable by any other app on the device, while exported="false" keeps it private to your app. Since Android 12 (API level 31), components with an intent filter must declare the attribute explicitly. The security risk is exporting a component that was meant to be internal, letting other apps launch screens or send data to services they should not reach. Set exported="false" unless a component genuinely needs to be public, and protect any that must be exported.
What you should know
- It controls cross-app access: exported components can be invoked by other apps.
- true is public, false is private: false keeps the component to your app.
- Android 12 requires it explicitly: components with intent filters must declare it.
- The risk is unintended exposure: an internal component left exported.
- Default to false: export only what genuinely must be public.
What does android:exported do?
It sets whether a component is reachable from outside your app. Android apps are made of components, activities for screens, services for background work, broadcast receivers for events, and each can be exported or not. When android:exported is true, other apps on the device can start that activity, bind to that service, or send broadcasts to that receiver; when it is false, only your own app can. Since Android 12, any component that declares an intent filter must set the attribute explicitly rather than relying on an implicit default, which forces a deliberate choice. So the attribute is the boundary between your app's internals and the rest of the device, and where you draw it determines what other apps can touch.
When is exported a risk?
When a component that assumes internal-only access is reachable by other apps. The table contrasts the cases.
| Component | exported setting | Risk |
|---|---|---|
| Launcher activity | true (required) | None; it must be public to launch the app |
| Activity handling a deep link | true | Acceptable if it validates the incoming data |
| Internal screen or service | false | Safe; only your app can reach it |
| Internal component left exported | true | Other apps can invoke it, potentially abusing it |
The danger case is the last one: a component built on the assumption that only your code calls it, but left exported, so another app can launch the screen, trigger the service, or feed it crafted input. If that component performs a sensitive action or trusts its input, an exported setting turns an internal assumption into an attack surface.
How do you secure exported components?
Default to private, and protect the ones that must be public. Set android:exported="false" on every component that does not need to be reachable by other apps, which is most of your internal screens and services. For components that genuinely must be exported, the launcher activity, a deep-link handler, a receiver for a system broadcast, treat their inputs as untrusted: validate every incoming intent and its extras, and do not assume the caller is your own app. Where a component should be reachable only by your own apps or a trusted set, protect it with a custom permission, ideally a signature-level permission so only apps signed with your key can call it. The principle is least exposure: export only what must be public, and harden whatever you do expose.
What to watch out for
The first trap is leaving a component exported by habit or because a generated manifest set it that way, when it was only ever meant for internal use. The second is exporting a component and then trusting its input, since an exported component can be fed crafted data by any app. The third is forgetting that since Android 12 the attribute is explicit, so a missing decision is now a decision you must make. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled APK or AAB against OWASP MASVS and surfaces the exported components declared in your manifest, so you can confirm nothing internal is exposed before you ship. Tightening the manifest and validating inputs is the fix you apply in the app.
What to take away
android:exporteddecides whether other apps can invoke your components, withtruepublic andfalseprivate to your app.- Since Android 12, components with an intent filter must declare the attribute explicitly, forcing a deliberate choice.
- The risk is an internal component left exported, letting other apps launch screens or message services they should not reach.
- Default to
exported="false", validate inputs on anything you must export, protect it with a signature permission where appropriate, and use a pre-submission scan such as PTKD.com to confirm what is exposed.


