menu
close_24px

BLOG

Android Component Security: Common Misconfigurations That Expose Mobile Apps

Explore common Android component and configuration vulnerabilities, how they’re exploited in real apps, and how to prevent exposure across the app lifecycle.
  • Posted on: Mar 31, 2026
  • By Aadarsh Anand
  • Read time 12 Mins Read
  • Last updated on: Mar 31, 2026

Reality check: most Android app vulnerabilities don’t come from code

When teams think about Android app security, the focus is usually on code for encryption, obfuscation, or binary protection.

But in practice, many of the most critical Android app vulnerabilities don’t originate in code at all.

They come from misconfigurations.

Issues in the AndroidManifest, insecure component exposure, and unsafe inter-app communication often create direct entry points for attackers. These are not edge cases. They are common, repeatable, and frequently exploited.

What gets shipped may be tested, but what is exposed is not always controlled.

Key takeaways

Most Android app vulnerabilities come from misconfigurations, not code flaws.

  • Exported components can expose internal functionality to other apps.
  • Weak permissions allow unauthorized access despite appearing secure.
  • Issues like intent redirection and task hijacking exploit component interactions.
  • Network and backend misconfigurations can lead to data leaks or system compromise.
  • These risks often persist into production without continuous validation.

Mobile app security depends on controlling exposure and behavior, not just scanning code.

The hidden gap: Android configuration is not continuously validated

Android applications rely heavily on configuration:

  • Component exposure (android:exported)
  • Permissions and access control
  • Intents for inter-app communication
  • Content Providers for data sharing

These are essential to the app's functionality and define how it behaves, not just internally but also within the broader app ecosystem.

In enterprise environments, however, these configurations are often treated as:

  • One-time setup decisions
  • Static definitions
  • Secondary to code-level security

This creates a fundamental gap.

Security is validated at build time, but exposure is defined by configuration and exploited at runtime.

Learn how mature teams enforce these checks directly in CI/CD pipelines.

Check out: How to Implement Mobile AppSec in a CI/CD Pipeline

Why Android misconfigurations lead to real-world attacks

Misconfigured Android components are not theoretical risks.

Configuration-level issues enable attackers to interact with the app in unintended ways. In practice, this leads to unauthorized access to internal components, data leakage across app boundaries, and execution of sensitive actions without user intent.

These vulnerabilities are particularly dangerous because they are:

  • Easy to exploit (often using standard tools like ADB)
  • Difficult to detect post-release
  • Often persistent across versions

Unlike traditional vulnerabilities, they don’t require sophisticated techniques, just access to exposed surfaces.

Unlike complex vulnerabilities, they rely on what the app exposes, not on how sophisticated the attack is.

Reframing the problem: from “Is the app secure?” to “What is exposed?”

Most teams ask:

Did we scan the app for vulnerabilities?

But Android security operates differently.

The more relevant question is:

What parts of this app are accessible to other apps and under what conditions?

Every exported component, permission, or intent handler becomes a potential entry point. Mature teams focus not just on identifying vulnerabilities but also on controlling exposure and continuously validating behavior.

Because:

In Android, security is defined by exposure, not just implementation.

Key Android configuration vulnerabilities

 

Unprotected exported components

Android components, Activities, Services, and Broadcast Receivers, can be exposed to other apps using the android:exported attribute in the AndroidManifest.xml.

If a component is marked as exported="true" without any protection, any app can launch it, send it data, or trigger its functionality. This can lead to unauthorized access to sensitive parts of the application.

For apps targeting Android 12 (API 31) and higher, an explicit value for android:exported is required for any component with an <intent-filter>.

Business impact

In real-world scenarios, this allows attackers to:

  • Leak data
    An attacker could launch a hidden activity that displays sensitive user data.

  • Initiate unauthorized actions
    A malicious app could start a service that performs a sensitive operation, like deleting data or making a payment, without user consent.

  • Denial of Service (DoS)
    An attacker could repeatedly launch a component, causing the app to become unstable or crash.

  • Bypassing UI flow
    Attackers can launch activities deep within the application, bypassing login screens or other security checks.

This is not a theoretical risk. It is a direct consequence of leaving internal functionality externally accessible.

How to check

Review the AndroidManifest.xml for components with android:exported="true" that lack a permission check.

Vulnerable example (AndroidManifest.xml)

 <activity

android:name=".SensitiveDataActivity"

android:exported="true" />

<service

android:name=".BackgroundDataSyncService"

android:exported="true" />

Secure Example (AndroidManifest.xml)

<activity

android:name=".SensitiveDataActivity"

android:exported="false" />

<service

android:name=".BackgroundDataSyncService"

android:exported="true"

android:permission="com.example.app.permission.SYNC_DATA" />

Exploit

An attacker can use the adb shell to directly launch an unprotected exported component.

# Launch an exported activity

adb shell am start -n com.victim.app/.SensitiveDataActivity

# Start an exported service

adb shell am startservice -n com.victim.app/.BackgroundDataSyncService

Non-signature protected components and weak permissions

Even when developers attempt to secure components using custom permissions, the protection level is critical.

A permission with android:protectionLevel="normal" or "dangerous" can be requested and granted to any other application.

For components that should be accessible only to apps signed with the same developer key, the protection level must be set to "signature". If it's not, a malicious app can simply request the permission and gain access to the component, defeating the intended security control.

Business impact

  • Privilege escalation
    A malicious app can gain the same privileges as the victim app to access sensitive components or data.

  • Trust model violation
    This flaw breaks the trust model between apps from the same developer, allowing a counterfeit or malicious app to interact with a legitimate one as if it were trusted.

  • Data theft and manipulation
    The attacker's app can communicate directly with the protected component to exfiltrate data or send malicious commands.

How to check

Review the AndroidManifest.xml for custom permissions and the components that use them. Ensure any permission guarding sensitive, internal components uses protectionLevel="signature".

Vulnerable permission definition

<permission

android:name="com.victim.app.permission.ACCESS_DATA"

android:protectionLevel="dangerous" />

<activity

android:name=".InternalToolActivity"

android:exported="true"

android:permission="com.victim.app.permission.ACCESS_DATA" />

Exploit

The attacker's app simply requests the "dangerous" permission in its own manifest and can then launch the component.

Attacker's Manifest (AndroidManifest.xml)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.attacker.app">

<uses-permission android:name="com.victim.app.permission.ACCESS_DATA" />

...

</manifest>

Improper custom permissions

Developers can create custom permissions to protect access to their app's components. However, the security of these permissions depends entirely on their protectionLevel.

  • normal: The system grants the permission automatically. It's intended for low-risk operations.
  • dangerous: The system prompts the user for approval at install time (on older Android versions) or at runtime.
  • signature: The system grants the permission only if the requesting app is signed with the same certificate as the app that defined the permission.

Using normal or dangerous for permissions that guard sensitive data or functionality is a critical mistake, as it allows any third-party app to potentially gain access.

This is a common cause of Android app data leakage vulnerabilities.

Business impact

 
  • Unauthorized access

    Malicious apps can gain access to functionality that should have been internal, leading to data leaks or unintended app behavior.

  • False sense of security

    Developers may believe their components are protected, while in reality, the protection can be easily bypassed by any app that requests the permission.

How to check for improper custom permissions

Audit all <permission> tags in the AndroidManifest.xml. Any permission that protects access between your own apps or to highly sensitive functionality should have android:protectionLevel="signature".

Vulnerable example

<permission

android:name="com.victim.app.permission.READ_USER_PROFILE"

android:label="Read User Profile"

android:protectionLevel="normal" />

Exploit

A malicious app only needs to declare <uses-permission android:name="com.victim.app.permission.READ_USER_PROFILE" /> in its manifest. The system will grant it automatically without user interaction, giving it access to the protected component.

Insecure Content Provider permissions

Content Providers are a primary mechanism for sharing data between applications and a major source of Android data exposure risks.

Their security is managed through android:readPermission and android:writePermission attributes, or more granularly with <path-permission>. If a Content Provider is exported but these permissions are missing, it may become world-readable or world-writable.

Another common mistake is defining a readPermission but forgetting a writePermission, allowing any app to insert, update, or delete data. SQL injection is also a risk if the provider's query methods build SQL statements directly from user-controlled input.

Business impact

  • Mass data leakage
    An attacker can dump the entire contents of the application's database or access its private files.

  • Data tampering
    Malicious apps can corrupt, delete, or modify the application's data, leading to app malfunction, user data loss, or financial fraud.

  • Application crashing
    Injecting malformed data can cause the application to crash when it attempts to process it.

How to check for insecure Content Providers

Review all <provider> tags in the manifest. Ensure they are not exported or are protected with appropriate signature-level permissions. Check the provider's query, insert, update, and delete methods for SQL injection vulnerabilities.

Vulnerable provider

<provider

android:name=".NotesProvider"

android:authorities="com.victim.app.notes"

android:exported="true"

android:readPermission="com.victim.app.READ_NOTES" />

Exploit

An attacker can use adb to interact with the misconfigured provider.

# Query a world-readable provider

adb shell content query --uri content://com.victim.app.notes/notes

# Insert data into a world-writable provider

adb shell content insert --uri content://com.victim.app.notes/notes --bind title:s:"Malicious Note" --bind content:s:"Injected data

 

Android component hijacking (task hijacking)

Component hijacking, often called Task Hijacking, exploits the way Android manages application tasks. The android:taskAffinity attribute in the AndroidManifest.xml allows activities from different apps to exist in the same task stack.

If misused, this can enable attackers to hijack application flows.

For example, if a malicious app sets its taskAffinity to the same value as a victim app, it can intercept the user's attempt to launch the victim app. When the user clicks the victim app's icon, Android may instead bring the malicious app's activity to the foreground, presenting a convincing phishing UI.

This is the basis for known vulnerabilities such as StrandHogg.

The impact here goes beyond technical compromise. It directly affects user trust and brand integrity.

Business impact

  • Credential theft
    This is a highly effective phishing attack. Users, believing they are on a legitimate login screen, will enter their credentials directly into an attacker-controlled UI.

  • UI redressing
    The malicious activity can mimic any part of the victim app to trick the user into performing sensitive actions or granting permissions.

  • Complete loss of user trust
    An attack that subverts the app's own UI is devastating to user confidence and brand reputation.

How to check for Android component hijacking

Review the taskAffinity for all activities in your manifest.

For most apps, this attribute should not be set, allowing the system to use the default affinity based on the package name.

For sensitive activities, explicitly set android:taskAffinity="" to prevent them from being moved to another task.

Attacker's manifest

<activity

android:name=".PhishingActivity"

android:taskAffinity="com.victim.app"

android:launchMode="singleInstance"

android:exported="true">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

Bypass

The exploit is the bypass. By installing an app with a carefully crafted manifest, an attacker can hijack another application's task.

Intent redirection vulnerability

Intent redirection occurs when an app receives an Intent and uses it to launch another component without proper validation.

In such cases, an attacker can craft an Intent that targets private or non-exported components.

A common pattern is an exported activity that accepts a nested Intent object within its extras. The activity then calls startActivity() on this nested Intent. If the application does not validate the contents of the nested Intent, a malicious app can supply a crafted Intent that points to a private, un-exported component within the victim app. This effectively turns the exported activity into a proxy that gives the attacker access to internal components.

Business impact

  • Internal component access
    Attackers can launch private activities, start internal services, or send broadcasts to private receivers, bypassing access controls.

  • Data exfiltration
    The redirected Intent could be used to launch a private component that returns sensitive data to the attacker's app.

  • Privilege escalation
    The malicious app can perform actions using the victim app's permissions.

How to check for intent redirection vulnerability

Review code where getParcelableExtra() is used to extract an Intent. Ensure the component and action of the nested Intent are validated against an allowlist before use.

Vulnerable code (Kotlin)

// An exported activity receives an Intent to forward

val redirectIntent = intent.getParcelableExtra<Intent>("redirect_intent")

if (redirectIntent != null) {

// The app launches the received Intent without validation!

startActivity(redirectIntent)

}

Exploit

The attacker crafts an Intent that targets a private activity and passes it as an extra.

# Create an intent that points to a private activity

adb shell am start -n com.victim.app/.RedirectProxyActivity \

-e redirect_intent "new Intent().setComponent(new ComponentName('com.victim.app', 'com.victim.app.PrivateSettingsActivity'))"

 

Dynamic broadcast receivers

Broadcast Receivers registered at runtime using registerReceiver() are often implicitly exposed unless explicitly protected.

While many broadcast receivers are declared in the manifest, they can also be registered dynamically at runtime using Context.registerReceiver().

A dynamically registered receiver is implicitly exported unless a permission is specified during registration. If a receiver that performs a sensitive action is registered without permission, any app on the device can invoke it by sending a broadcast Intent.

Business impact

  • Triggering sensitive actions
    An attacker could send a broadcast that causes the app to delete files, upload data, or enter a
    bad state.

  • Denial of Service (DoS)A malicious app could flood the dynamic receiver with broadcasts, consuming resources and potentially crashing the victim application.

  • Data injection
    If the receiver processes data from the broadcast Intent, an attacker can inject malicious or malformed data.

How to check for dynamic broadcast receivers

Search the codebase for all calls to registerReceiver(). Ensure that any receiver handling sensitive actions is registered with a signature-level permission.

Vulnerable code (Kotlin)

// Receiver is registered without any permission

val receiver = MySensitiveReceiver()

val filter = IntentFilter("com.victim.app.DO_SENSITIVE_ACTION")

registerReceiver(receiver, filter)

Secure code (Kotlin)

val receiver = MySensitiveReceiver()

val filter = IntentFilter("com.victim.app.DO_SENSITIVE_ACTION")

// Register with a signature-level permission

registerReceiver(receiver, filter, "com.victim.app.permission.SENSITIVE", null)

Exploit

An attacker can use adb or a malicious app to send a broadcast to the unprotected receiver.

adb shell am broadcast -a com.victim.app.DO_SENSITIVE_ACTION

 

Fragment injection

Fragment injection vulnerability occurs when an exported activity dynamically loads Fragments based on a class name provided as an Intent extra.

If the app does not validate the provided class name, an attacker can force the activity to load any exported Fragment from the app's classpath, or even from libraries included by the app. This could allow an attacker to display a misleading UI or trigger unintended logic within the loaded fragment.

Business impact

  • UI manipulation
    An attacker could replace an expected fragment with one that phishes for user credentials or displays false information.

  • Information leakage
    If a fragment intended for internal use is loaded, it might display sensitive device or user information.

  • Logic bypass
    Loading an unintended fragment could bypass security steps or business logic in the app's normal flow.

How to check for fragment injection

Review exported activities that load fragments.

If the fragment class name is derived from an Intent extra, ensure it is validated against a strict allowlist of safe fragments.

Vulnerable code (Kotlin)

// This activity is exported

class DynamicFragmentActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

val fragmentClassName = intent.getStringExtra("fragment_to_load")


// The class name is used without validation!

val fragment = Class.forName(fragmentClassName).newInstance() as Fragment

supportFragmentManager.beginTransaction()

.replace(R.id.fragment_container, fragment)

.commit()

}

}

Exploit

An attacker can use adb to launch the activity and specify a fragment they want to inject.

adb shell am start -n com.victim.app/.DynamicFragmentActivity \

-e fragment_to_load "com.attacker.MaliciousFragment"

 

Enabled application backup

The android:allowBackup attribute in the manifest controls whether the application's data can be backed up using Android's backup mechanisms, including adb backup. If this flag is set to true (which is the default for apps targeting below Android 6.0), an attacker with physical access to an unlocked device can use ADB to extract the application's private data from its files and shared_prefs directories.

Business impact

  • Complete data exfiltration
    An attacker with temporary physical access can steal sensitive data stored on the device, such as authentication tokens, cached user data, API keys, and other secrets.

  • Offline analysis
    Once the data is extracted, the attacker can analyze it offline to plan further attacks or steal user credentials.

How to check for application backup?

Inspect the <application> tag in AndroidManifest.xml. It should explicitly be set to android:allowBackup="false".

Vulnerable configuration

<application

android:label="@string/app_name"

android:icon="@mipmap/ic_launcher"

android:allowBackup="true">

...

</application>
Secure configuration
<application

android:label="@string/app_name"

android:icon="@mipmap/ic_launcher"

android:allowBackup="false">

...

</application>

Exploit

An attacker with USB debugging enabled on the device can run the following command.

adb backup -f backup.ab com.victim.app

The resulting backup.ab file can then be unpacked to reveal the application's private data.

Network security misconfigurations

This category covers several common network-related flaws. A primary one is allowing cleartext (unencrypted HTTP) traffic by setting android:usesCleartextTraffic="true" in the manifest or in a Network Security Configuration file.

Allowing cleartext traffic exposes applications to interception attacks, like Man-in-the-Middle (MitM) attacks on insecure networks

Business impact

  • Data interception
    An attacker on the same network (e.g., public Wi-Fi) can intercept and read sensitive data sent between the app and its server, including credentials and personal information.

  • Session hijacking
    Intercepted session cookies can be used to hijack a user's session.

How to check for network security misconfigurations

  • Inspect AndroidManifest.xml for android:usesCleartextTraffic="true".
  • Review res/xml/network_security_config.xml for domains that permit cleartext traffic.

Vulnerable network config (network_security_config.xml)

<network-security-config>

<base-config cleartextTrafficPermitted="true" />

</network-security-config>

Exploit

An attacker can use a proxy tool like Burp Suite or mitmproxy to intercept and modify the application's unencrypted traffic.

Insecure connections to external services

This vulnerability occurs when an application directly connects to external backend services, such as databases (MySQL, Firebase) or caching servers (Redis), from the client-side code. It is a severe architectural flaw because the connection details, including IP addresses, ports, and often credentials, must be stored within the APK.

An attacker can easily decompile the app, extract these hardcoded secrets, and gain direct access to the backend infrastructure.

This type of flaw extends beyond the app as it can lead to full system compromise.

Business impact

  • Backend system compromise
    An attacker can connect directly to the database or service, potentially stealing, modifying, or deleting all application data.

  • Infrastructure takeover
    Gaining access to one service can provide a foothold for an attacker to move laterally and compromise other parts of the backend infrastructure.

  • Reputational and financial catastrophe
    A direct breach of backend systems is one of the most damaging security incidents possible, leading to massive data loss, regulatory fines, and a complete collapse of user trust.

How to check for insecure connections to external services

Decompile the application and search the source code (Java/Kotlin and native libraries) for hardcoded IP addresses, hostnames, and credentials. Look for connection strings or APIs related to direct database or service connections.

Vulnerable code example (Kotlin)

// DO NOT DO THIS IN A CLIENT APP

val redisHost = "192.168.1.100"

val redisPort = 6379

val redisPassword = "insecure_password123"

// Code to connect directly to Redis...

Exploit

An attacker decompiles the app, finds the credentials, and connects to the service.

# After finding credentials in the decompiled code

redis-cli -h 192.168.1.100 -p 6379 -a "insecure_password123"

192.168.1.100:6379> KEYS *

1) "user:123:session"

2) "user:456:profile"

The bigger pattern: exposure across the lifecycle

These vulnerabilities may appear distinct, but they share a common root cause:

Lack of continuous visibility into how the app is exposed and behaves beyond development.

Most issues:

  • Originate during development
  • Are missed during validation
  • Persist into production

Traditional approaches focus on scanning code or binaries, but exposure is defined by configuration and exploited at runtime.

Platforms like Appknox help address this by enabling continuous validation of application behavior and configuration across build and release stages, ensuring these issues are identified before they become production risks.

Conclusion: security doesn’t fail in code. It fails in exposure.

Android applications rarely fail because of a single critical bug. They fail because exposure is not fully understood or controlled.

Configuration defines what is accessible. Runtime behavior determines how it is exploited.

What you expose is what attackers use.

The shift is not toward more scanning, but toward continuous visibility, validation, and control across the lifecycle.

You’ve seen where mobile app security breaks in practice. The next step is choosing a platform that actually closes these gaps.

Use the mobile AppSec evaluation framework to assess what works in real-world environments.

Download now!

FAQs

 

What are common Android component security vulnerabilities?

Common vulnerabilities include improperly exported components, weak permission models, insecure Content Providers, intent redirection issues, and task hijacking. These are typically caused by configuration flaws rather than code-level bugs.

Why are exported components risky in Android apps?

Exported components allow external apps to interact with internal functionality. Without proper restrictions, they can be used to access sensitive data, trigger actions, or bypass intended application flows.

What is an intent redirection vulnerability?

Intent redirection occurs when an app launches another component using an unvalidated Intent received from an external source. Attackers can exploit this to access internal components or perform unauthorized actions.

How do misconfigured permissions affect security?

Permissions with weak protection levels can be requested by any app, allowing unauthorized access to sensitive components. This breaks the intended security boundary between applications.

What is component hijacking in Android?

Component hijacking allows a malicious app to intercept or mimic parts of another app’s UI or workflow, often to steal credentials or mislead users into performing sensitive actions.

How can insecure Content Providers be exploited?

If not properly secured, Content Providers can allow attackers to read, modify, or delete application data. They may also be vulnerable to injection attacks if inputs are not validated.

How can teams prevent configuration-based vulnerabilities?

Teams should restrict component exposure, enforce strong permission models, validate all external inputs, avoid hardcoded credentials, and disable insecure configurations. Most importantly, they should continuously validate these controls across the app lifecycle.