The following sample app attempts to start InternalActivity for app-internal communication by sending an implicit intent with the custom action org.owasp.mastestapp.INTERNAL_ACTION. This approach is insecure because another app can register a matching <intent-filter> and become a candidate during Android's intent resolution. For more details on the intent resolution mechanism, see Explicit vs Implicit Intents.
The intent in this sample is implicit because it relies on setAction without explicitly defining the target package or component. For the secure alternative, see Use Explicit Intents for Internal IPC.
packageorg.owasp.mastestappimportandroid.content.Contextimportandroid.content.Intent// SUMMARY: This sample demonstrates the insecure use of implicit intents for internal communication.classMastgTest(privatevalcontext:Context){funmastgTest():String{valr=DemoResults("0x01")// FAIL: [MASTG-TEST-0372] The app uses an implicit intent to start an internal activity.valimplicitIntent=Intent().apply{action="org.owasp.mastestapp.INTERNAL_ACTION"putExtra("user_id","12345")putExtra("session_token","abcde-fghij-12345")addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)}try{context.startActivity(implicitIntent)r.add(Status.FAIL,"Launched internal activity via implicit intent")}catch(e:Exception){r.add(Status.ERROR,e.toString())}/* // PASS: [MASTG-TEST-0372] The app uses an explicit intent for internal communication. val explicitIntent = Intent(context, InternalActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } try { context.startActivity(explicitIntent) r.add(Status.PASS, "Launched internal activity via explicit intent") } catch (e: Exception) { r.add(Status.ERROR, e.toString()) } */returnr.toJson()}}classInternalActivity:android.app.Activity(){overridefunonCreate(savedInstanceState:android.os.Bundle?){super.onCreate(savedInstanceState)valtextView=android.widget.TextView(this)textView.text="Internal Activity"textView.textSize=24ftextView.gravity=android.view.Gravity.CENTERsetContentView(textView)}}
<?xml version="1.0" encoding="utf-8"?><manifestxmlns:android="http://schemas.android.com/apk/res/android"><application><activityandroid:name="org.owasp.mastestapp.MainActivity"android:exported="true"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity><!-- Internal activity with an intent-filter, making it a resolver candidate --><activityandroid:name="org.owasp.mastestapp.InternalActivity"android:exported="true"><intent-filter><actionandroid:name="org.owasp.mastestapp.INTERNAL_ACTION"/><categoryandroid:name="android.intent.category.DEFAULT"/></intent-filter></activity></application></manifest>
Attacker App Registering for Internal Implicit Intent provides an example attacker app that declares a matching <intent-filter> for org.owasp.mastestapp.INTERNAL_ACTION. It demonstrates how another app can become a candidate for handling this sample app's implicit intent.
rules:-id:mastg-android-implicit-intent-internal-communicationpatterns:-pattern:|$INTENT=newIntent(...);...$INTENT.setAction($ACTION);...$CONTEXT.startActivity($INTENT);-pattern-not:|$INTENT=newIntent(...);...$INTENT.setPackage(...);...$CONTEXT.startActivity($INTENT);-pattern-not:|$INTENT=newIntent(...);...$INTENT.setComponent(...);...$CONTEXT.startActivity($INTENT);-pattern-not:|$INTENT=newIntent($CONTEXT,$CLASS);...$CONTEXT.startActivity($INTENT);message:"[MASVS-CODE-4] The app uses an implicit intent for internal component communication. Use explicit intents by specifying the package or component."languages:[java]severity:WARNINGmetadata:summary:Detectsimplicitintentsusedforinternalcomponentcommunicationwithoutspecifyingapackageorcomponent.
run.sh
123
#!/bin/bash# SUMMARY: This script uses semgrep to detect implicit intents in the source code.NO_COLOR=truesemgrep--config../../../../rules/mastg-android-implicit-intent-internal-communication.ymlMastgTest_reversed.java--text>output.txt
The test case fails because the app uses an implicit intent (org.owasp.mastestapp.INTERNAL_ACTION) for app-internal communication with InternalActivity.
The action is app-specific and the manifest declares InternalActivity as the component intended to handle it, but the reported dispatch does not name that component or restrict the target package. The reported block does not show a target-defining call such as setPackage, setClass, setClassName, setComponent, or an explicit Intent(context, Class) constructor before dispatch. Another app can declare a matching <intent-filter> and become a candidate during Android intent resolution.