tmolavi/mcp-agent-skills-hub/android-intent-security

Claude Code and agent skill by tmolavi/mcp-agent-skills-hub

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Best practices for Android Intent security. Use this skill when auditing

Install

npx vskill@latest install tmolavi/mcp-agent-skills-hub/android-intent-security

SKILL.md

This skill provides guidelines and patterns to secure Android components (Activities, Services, Broadcast Receivers, Content Providers) and handle Intents safely, preventing privilege escalation and unauthorized access.

Glossary

  • Intent: An asynchronous messaging object used to request an action from another app component.
  • Exported component: A component (android:exported="true") that can be launched by other apps on the device.
  • Sticky intent: A broadcast intent that remains in the system cache after it's sent, allowing any app to retrieve its contents.
  • Signature permission: A permission whose protection level is set to signature, granted only to apps signed with the same developer key.
  • onNewIntent: An activity lifecycle callback invoked when an activity is launched with FLAG_ACTIVITY_SINGLE_TOP and is already running at the top of the history stack.
  • PendingIntent: A token granted to a foreign application (for example, system services) allowing it to execute a predefined Intent with the creator's permissions.
  • Mutable PendingIntent: A PendingIntent whose underlying Intent parameters can be modified by the receiving application.
  • ContentProvider: A component that encapsulates data and provides it to other applications via standard query/insert interfaces.
  • IntentSanitizer: A utility class in AndroidX Core used to build a safe, sanitized copy of an incoming Intent by filtering out unauthorized components, actions, or extras.
  • Intent redirection (forwarding): A vulnerability where an application receives an intent from an untrusted source and uses it to launch a private, non-exported component.

Prerequisites

  • The agent MUST be able to describe the function and security implications of onCreate, onNewIntent, and the singleTop launch mode.
  • The agent MUST be able to declare <activity>, <service>, <receiver>, and <provider> tags in AndroidManifest.xml and define their android:exported and android:permission attributes.
  • The agent MUST be able to implement signature verification checks using PackageManager.

Limitations

  • This skill focuses on local inter-component and inter-app communication security on the Android platform.
  • This skill doesn't cover network security, web integration, or host-to-server security.

Setup and dependencies

  • Android SDK: Minimum API Level 23 (Android 6.0) is required for standard hardware-backed keystore operations and component validation.
  • AndroidX Core Library: androidx.core:core:1.9.0 or higher is mandatory to leverage IntentSanitizer.
  • Standard API access: Standard Android PackageManager APIs are required for runtime component verification.

* * *

Intent security logic and decisions

1. Intent routing comparison

Evaluate the security features of different intent delivery methods:

Intent Delivery MethodScopeRecommended Use Case
Explicit Intent (Internal)App PrivateLaunching internal activities/services
Implicit IntentSystem WideLaunching system camera, dialer, or sharing
Local Broadcasts (LocalBroadcastManager) (DEPRECATED)App PrivateInternal asynchronous event routing. Deprecated: Use in-app observers like Kotlin Flows/SharedFlow, LiveData, or reactive patterns instead.
System BroadcastsSystem WideReceiving system events (NFC, Bluetooth)
2. PendingIntent mutability flag options

Evaluate the security implications of PendingIntent mutability flags:

Flag NameMutabilityRecommended Use Case
PendingIntent.FLAG_IMMUTABLEImmutableDefault for almost all PendingIntents, such as alarms and notifications
PendingIntent.FLAG_MUTABLEMutableInline notifications replies, slice actions (requires explicit target intent)
3. Intent handling and redirection logic

IF (the component receives a nested Intent as an extra) { IF (AndroidX Core 1.9.0+ and higher is available) { MUST construct an IntentSanitizer to explicitly allowlist components, actions, data, and extras. MUST call sanitizeByThrowing() or sanitizeByFiltering() before launching. } ELSE { MUST verify that the nested Intent's target package matches the current application package. MUST verify that the target component of the nested Intent is publicly exported. } NEVER launch the nested Intent directly without validation. } ELSE IF (the component handles broadcasts) { MUST rely on the system's Protected Broadcast mechanism for system events (which guarantees the sender is the system framework). MUST protect custom receivers with signature-level permissions or use RECEIVER_NOT_EXPORTED for dynamic receivers to restrict the sender. }

4. PendingIntent security logic

IF (a PendingIntent is created for delivery to another application) { MUST use PendingIntent.FLAG_IMMUTABLE by default. IF (the PendingIntent must be mutable) { MUST set the explicit target component or package name on the base Intent. NEVER create an implicit, mutable PendingIntent. } }

5. ContentProvider security logic

IF (the ContentProvider is only for internal app use) { MUST set android:exported="false". } ELSE { MUST protect it with android:readPermission and android:writePermission. MUST set android:grantUriPermissions="false" unless temporary URL access is strictly required. }

6. Service caller verification logic

IF (an exported service communicates with trusted sister/partner apps) { MUST retrieve the calling UID using Binder.getCallingUid() and resolve it to package names using PackageManager.getPackagesForUid(). MUST verify that the calling package signature fingerprint matches your trusted certificate hash. }

* * *

Code and configuration patterns

1. Safe intent redirection (manual verification)

Validate the target of a nested intent before launching it when modern sanitization libraries are unavailable.

  • Expected Inputs:
  • An incoming Intent containing a nested Intent extra named EXTRA_NESTED_INTENT.
  • Expected Outputs:
  • Launches the target component if safe; throws SecurityException if validation fails.
kotlin
fun safeIntentRedirectionManual() {
val nestedIntent = IntentCompat.getParcelableExtra(intent, "EXTRA_NESTED_INTENT", Intent::class.java)
if (nestedIntent != null) {
// 1. Check for URI permission grants to prevent URI permission bypass
val hasUriPermissionGrants = (
nestedIntent.flags and (
Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
)
) != 0
if (hasUriPermissionGrants) {
throw SecurityException("Nested intent contains forbidden URI permission grant flags!")
}
val pm = packageManager
val target = nestedIntent.resolveActivity(pm)
if (target != null) {
// 2. Verify target is within the same package
if (target.packageName != packageName) {
throw SecurityException("Cross-app intent redirection is forbidden!")
}
try {
// 3. Verify target activity is exported
val info = pm.getActivityInfo(target, 0)
if (!info.exported) {
throw SecurityException("Target activity is private: ${target.className}")
}
// 4. Explicitly set the component to prevent intent interception
nestedIntent.component = target
// Safe to launch
startActivity(nestedIntent)
} catch (e: PackageManager.NameNotFoundException) {
Log.e("Security", "Failed to resolve target activity", e)
}
}
}
}

<br />

2. Safe intent redirection using IntentSanitizer

Filter or reject dynamic intents using AndroidX IntentSanitizer (AndroidX Core 1.9.0+).

  • Expected Inputs:
  • An untrusted incoming Intent.
  • Expected Outputs:
  • Intent: A sanitized copy containing only allowlisted components, categories, and actions. Throws SecurityException on violations if using sanitizeByThrowing().
kotlin
fun safeIntentRedirectionSanitizer() {
val untrustedIntent = IntentCompat.getParcelableExtra(intent, "EXTRA_NESTED_INTENT", Intent::class.java)
if (untrustedIntent != null) {
// Define the strict boundaries for allowed redirection target
val sanitizer = IntentSanitizer.Builder()
.allowComponent(ComponentName("com.example.app", "com.example.app.SafeTargetActivity")) // Explicitly allowed target
.allowAction(Intent.ACTION_VIEW) // Explicitly allowed actions
.allowDataWithAuthority("com.example.app.provider") // Allowed URI authority
.allowType("text/plain") // Allowed mime type
.allowExtra("user_display_name", String::class.java) // Safe type-enforced extras
// Note: URI permission flags are NOT allowed, so the sanitizer will automatically strip or throw on them
.build()
try {
// Option A: Throws SecurityException if the intent violates policies
val safeIntent = sanitizer.sanitizeByThrowing(untrustedIntent)
startActivity(safeIntent)
} catch (e: SecurityException) {
Log.e("SECURITY_ALERT", "Attempted launch of non-allowlisted intent blocked", e)
}
// Option B: Silently filter and launch only the authorized parts (no exception thrown)
// val filteredIntent = sanitizer.sanitizeByFiltering(untrustedIntent)
// startActivity(filteredIntent)
}
}

<br />

3. Custom signature permission protection

Declare a custom signature-level permission in the manifest to secure family app communication.

  • Expected Inputs: Manifest configuration.
  • Expected Outputs: An activity that can only be launched by apps signed with the same developer certificate.
xml
<permission
android:name="com.example.snippets.permission.INTERNAL_COMMUNICATION"
android:protectionLevel="signature" />

<br />

xml
<activity
android:name=".intents.InternalSharingActivity"
android:exported="true"
android:permission="com.example.snippets.permission.INTERNAL_COMMUNICATION">
<intent-filter>
<action android:name="com.example.snippets.ACTION_SHARE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<br />

4. Safe onNewIntent lifecycle verification (warm boot protection)

Ensure that activities reusing dynamic intents (for example, in background launch paths) apply the same strict security filters inside onNewIntent.

  • Expected Inputs:
  • newIntent (Intent): The newly delivered intent.
  • Expected Outputs:
  • Executes processing logic only if the new intent passes security validation.
kotlin
override fun onNewIntent(newIntent: Intent) {
super.onNewIntent(newIntent)
// Set the intent to ensure intent returns the new one
intent = newIntent
// Validate the intent payload
if (validateIntent(newIntent)) {
processIntentPayload(newIntent)
} else {
Log.w("SECURITY_ALERT", "Received invalid or insecure intent during warm boot")
}
}
private fun validateIntent(intent: Intent): Boolean {
return intent.hasExtra("VALID_PAYLOAD_MARKER")
}

<br />

5. Secure PendingIntent creation

Enforce immutability unless mutability is explicitly required.

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
8
7-day trend score
11

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/tmolavi/mcp-agent-skills-hub/android-intent-security/badge)](https://verified-skill.com/skills/tmolavi/mcp-agent-skills-hub/android-intent-security)

Something wrong with this skill or its page? Tell us.