TL;DR: Activities, services, broadcast receivers and content providers are Android's IPC entry points. An exported component can be invoked by any app on the device, so it is a public API: it needs a permission check (often signature-level for components meant only for your own apps) and it must validate every extra, URI and file it receives. The classic bugs are exported components that perform privileged actions without checking the caller, content providers that expose private data or files (including through path traversal), intent redirection where an app forwards an attacker-supplied intent with its own privileges, implicit intents carrying sensitive data that another app can intercept, and mutable pending intents. Fix by exporting nothing you do not need, requiring permissions, using explicit intents, and treating IPC input as untrusted.
How to approach it
Explain what "exported" means and why Android 12 forced developers to declare it. Then go through the four component types, the typical bug for each, and the fix. Frame it as API security inside the phone: same questions, different transport.
A strong answer
Other app
possibly malicious
Intent
extras, URI, file
Exported component
activity, service, provider
Privileged action
with your app's rights
Controls
Do not export by default
- android:exported is explicit since Android 12
Permission check
- Signature-level for your own apps
Validate inputs
- No raw paths, no forwarded intents, no blind URI grants
What exported means. A component with android:exported="true" (or, before Android 12, one with an intent filter and no explicit declaration) can be started or bound by other apps. Since Android 12, components that declare intent filters must state android:exported explicitly, which removed a class of accidental exposure but not deliberate or careless true values.
Bugs by component type.
| Component | Typical vulnerability | Fix |
|---|---|---|
| Activity | An exported screen that performs an action (change email, confirm payment, open an internal WebView) when launched with crafted extras | Do not export; if needed, require a permission and validate extras; never skip authentication because the screen was opened by intent |
| Service | An exported service that runs privileged operations for any caller | Signature-level permission; check the caller's identity (Binder.getCallingUid) for bound services |
| Broadcast receiver | Accepts spoofed broadcasts that trigger actions, or the app sends sensitive data in broadcasts other apps can receive | Permission-protected receivers; explicit or local broadcasts; never put secrets in implicit broadcasts |
| Content provider | Exposes a private database or files; openFile with a URI path that traverses outside the intended directory; SQL injection through projection or selection | exported="false" by default; grantUriPermissions for one-off sharing; canonicalise paths and check they stay inside the base directory; parameterised queries |
Intent redirection: the confused deputy. App A has an exported activity that takes an Intent from its extras and calls startActivity with it. A malicious app B passes an intent targeting one of A's private, non-exported components, or a content URI with A's read permission flags. A, acting with its own identity, opens that private component or grants B access to A's files. The fix is to never launch an intent taken from untrusted input, or to validate its target component and strip permission grant flags.
Implicit intents and data leakage. Sending sensitive data in an implicit intent lets any app that registers a matching filter receive it. Use explicit intents (set the target package and class) for anything sensitive.
Pending intents. A PendingIntent lets another app perform an action with your app's identity later. A mutable pending intent with an empty or implicit base intent can be filled in by the receiver to target something you did not intend. Use FLAG_IMMUTABLE and explicit base intents.
How to find these. Read the manifest for exported components and their permissions; enumerate them on a test device; for each, find the code handling incoming intents or URIs and trace the inputs to sensitive actions (file access, network requests, WebView loads, account changes). Static analysis tools flag many patterns; manual review finds the business logic.
Same lens on iOS. iOS has fewer IPC surfaces, but custom URL schemes, universal links, app extensions and shared app-group containers raise the same questions: who can call this, and does the handler validate input and require authentication?
What interviewers probe next
- "A component is exported but requires a 'normal' protection-level permission. Is it protected?" No: any app can request a normal permission and get it at install. Use signature-level for internal use.
- "How would an attacker exploit a content provider's openFile?" By supplying a URI whose path, after decoding, escapes the intended directory (for example
../segments), reaching the app's private files. Canonicalise and check the prefix. - "Your app needs to receive shares from other apps. What do you validate?" MIME type, size, the URI scheme and authority, and that reading the content cannot reach your own private files; process it as untrusted input.
What if?
What if · interview follow-ups
Hold your answer as the constraints change
An Android app exposes several activities, services and a content provider to other apps for integrations.
Start here
What are exported components?
Who can call an exported component?
Activities, services, broadcast receivers and content providers are Android's IPC entry points. An exported component can be invoked by any app on the device, so it is a public API.
Carry it forwardExported components are public APIs.
Weak answerAssuming only your apps call them.
Constraint changes
How should access be controlled?
Which components need to be exported at all?
With permission checks, often signature-level for components meant only for your own apps, and explicit exported flags. Components not meant for others should not be exported.
Carry it forwardExport only what is needed, with permissions.
Weak answerRelying on intent filters as protection.
Constraint changes
Why must inputs be validated?
What does the component do with the intent data?
Intent extras and URIs from other apps are attacker-controlled. Components that use them to open files, load URLs or perform actions can be abused to read data or act as the user.
Carry it forwardValidate every input from other apps.
Weak answerTrusting extras because the sender has permission.
Constraint changes
What are the risks with content providers?
Can another app query the provider directly?
Providers without permissions expose data, and path traversal or SQL injection in provider queries can leak more. Granting URI permissions too broadly also leaks files.
Carry it forwardProtect providers with permissions and safe queries.
Weak answerExported providers with no read permission.
Constraint changes
How do you check the app?
How would you notice a new exported component?
Review the manifest for exported components, test each with an unprivileged test app, and add lint and CI checks that flag new exported components without permissions.
Carry it forwardManifest review, testing and CI checks.
Weak answerChecking only before the first release.
Now defend it
How would you secure the app's components?
Export only components meant for others, protect them with permissions (signature-level for your own apps), validate all intent data and URIs, secure content providers with permissions and safe queries, avoid broad URI grants, test with an unprivileged app, and flag new exports in CI.
How it's scored
Weak: "Don't export components."
Hire: Explains exported components as an attack surface, names permission checks and explicit intents, and identifies content provider exposure.
Strong Hire: Covers each component type with its typical bug, explains intent redirection as a confused deputy, implicit intent leakage, mutable pending intents, provider path traversal, the Android 12 rule, how to enumerate and review, and the iOS equivalents.
Common mistakes
- Protecting a component with a normal-level permission.
- Forwarding intents received from other apps.
- Putting tokens or personal data into implicit intents or broadcasts.
- Trusting that a screen was reached only through the app's own flow.