Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0042/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MASTestApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.MASTestApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".VulnerableActivity" android:exported="true">>
<intent-filter>
<action android:name="org.owasp.mastestapp.VULNERABLE_ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="35" android:compileSdkVersionCodename="15" package="org.owasp.mastestapp" platformBuildVersionCode="35" platformBuildVersionName="15">
<uses-permission android:name="android.permission.INTERNET"/>
<permission android:name="org.owasp.mastestapp.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>
<uses-permission android:name="org.owasp.mastestapp.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
<application android:allowBackup="true" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:dataExtractionRules="@xml/data_extraction_rules" android:debuggable="true" android:extractNativeLibs="false" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MASTestApp">
<activity android:exported="true" android:name="org.owasp.mastestapp.MainActivity" android:theme="@style/Theme.MASTestApp">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:exported="true" android:name="org.owasp.mastestapp.VulnerableActivity"> &gt; <intent-filter>
<action android:name="org.owasp.mastestapp.VULNERABLE_ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:exported="true" android:name="androidx.compose.ui.tooling.PreviewActivity"/>
<activity android:exported="true" android:name="androidx.activity.ComponentActivity"/>
<provider android:authorities="org.owasp.mastestapp.androidx-startup" android:exported="false" android:name="androidx.startup.InitializationProvider">
<meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer" android:value="androidx.startup"/>
<meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup"/>
<meta-data android:name="androidx.profileinstaller.ProfileInstallerInitializer" android:value="androidx.startup"/>
</provider>
<uses-library android:name="androidx.window.extensions" android:required="false"/>
<uses-library android:name="androidx.window.sidecar" android:required="false"/>
<receiver android:directBootAware="false" android:enabled="true" android:exported="true" android:name="androidx.profileinstaller.ProfileInstallReceiver" android:permission="android.permission.DUMP">
<intent-filter>
<action android:name="androidx.profileinstaller.action.INSTALL_PROFILE"/>
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.SKIP_FILE"/>
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.SAVE_PROFILE"/>
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.BENCHMARK_OPERATION"/>
</intent-filter>
</receiver>
</application>
</manifest>
42 changes: 42 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0042/MASTG-DEMO-0042.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
platform: android
title: Implicit Intent Hijacking
id: MASTG-DEMO-0042
code: [kotlin]
test: MASTG-TEST-0026
---

### Sample

The code snippet shows that an implicit intent is used to launch an activity using Intent without specifying the target component. This could allow malicious applications to hijack the intent.

{{ MastgTest.kt # MastgTest_reversed.java }}

### MastgTestAttacker.kt

The code includes an application code that demonstrates how an attacker could exploit this configuration to launch internal activities or inject malicious data by sending crafted intents.

{{ MastgTestAttacker.kt }}

### VulnerableActivity.kt

A sample internal component of the application, which contains any sensitive data.

{{ VulnerableActivity.kt }}

### Steps

1. Install the attacker app on a device using @MASTG-TECH-0004.
2. Press the button to trigger the malicious intent.

{{ MastgTestAttacker.kt }}

### Observation

The output shows that the attacker's application was able to successfully launch the target application's internal VulnerableActivity using implicit intent. This confirms that the activity was exported and could be reached without explicit targeting.

### Evaluation

The test fails due to the following exported activity being accessible via an implicit intent:

- The `VulnerableActivity` is declared with `android:exported="true"` and includes an `<intent-filter>`, which allows it to be triggered by any external application without requiring explicit targeting or permissions. This confirms that internal components intended for use only within the app can be exposed and misused if not properly secured.
20 changes: 20 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0042/MastgTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.owasp.mastestapp

import android.content.Context
import android.content.Intent
import android.util.Log

class MastgTest(private val context: Context) {

fun mastgTest(): String {
val sensitiveString = "Hello from the OWASP MASTG Test app. Try to send intent."
Log.d("MASTG-TEST", sensitiveString)
return sensitiveString
}

fun triggerVulnerableIntent() {
val intent = Intent()
intent.action = "org.owasp.mastestapp.VULNERABLE_ACTION"
context.startActivity(intent) // Vulnerable: Starting activity with implicit intent
}
}
23 changes: 23 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0042/MastgTestAttacker.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.intenttrigger

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val exploitButton: Button = findViewById(R.id.exploitButton)

exploitButton.setOnClickListener {
val exploitIntent = Intent()
exploitIntent.action = "org.owasp.mastestapp.VULNERABLE_ACTION" // The vulnerable intent action
exploitIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

startActivity(exploitIntent) // Launch the vulnerable activity
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.owasp.mastestapp

import android.app.Activity
import android.os.Bundle
import android.widget.TextView

class VulnerableActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val textView = TextView(this)
textView.text = "FLAG{IMPLICIT_INTENT_VULNERABILITY}"
textView.textSize = 20f

setContentView(textView)
}
}
32 changes: 32 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0042/MastgTest_reversed.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.owasp.mastestapp;

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import androidx.constraintlayout.widget.ConstraintLayout;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;

/* compiled from: MastgTest.kt */
@Metadata(d1 = {"\u0000\u001e\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\u0002\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\u000f\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0004\b\u0004\u0010\u0005J\u0006\u0010\u0006\u001a\u00020\u0007J\u0006\u0010\b\u001a\u00020\tR\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\n"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "<init>", "(Landroid/content/Context;)V", "mastgTest", "", "triggerVulnerableIntent", "", "app_debug"}, k = 1, mv = {2, 0, 0}, xi = ConstraintLayout.LayoutParams.Table.LAYOUT_CONSTRAINT_VERTICAL_CHAINSTYLE)
/* loaded from: classes4.dex */
public final class MastgTest {
public static final int $stable = 8;
private final Context context;

public MastgTest(Context context) {
Intrinsics.checkNotNullParameter(context, "context");
this.context = context;
}

public final String mastgTest() {
Log.d("MASTG-TEST", "Hello from the OWASP MASTG Test app. Try to send intent.");
return "Hello from the OWASP MASTG Test app. Try to send intent.";
}

public final void triggerVulnerableIntent() {
Intent intent = new Intent();
intent.setAction("org.owasp.mastestapp.VULNERABLE_ACTION");
this.context.startActivity(intent);
}
}
33 changes: 33 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0043/MASTG-DEMO-0043.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
platform: android
title: Implicit Intent Hijacking
id: MASTG-DEMO-0043
code: [kotlin]
test: MASTG-TEST-0027
---

### Sample

The code snippet shows that an implicit intent is used to launch an activity using Intent without specifying the target component. This could allow malicious applications to hijack the intent.

{{ ../MASTG-DEMO-0042/MastgTest_reversed.java # ../MASTG-DEMO-0042/AndroidManifest_reversed.xml }}

### Steps

Let's run our @MASTG-TOOL-0110 rule against the manifest file and code.

{{ ../../../../rules/mastg-android-implicit-intent-start-activity.yml }}

{{ ../../../../rules/mastg-android-exported-activity.yml }}

{{ run.sh }}

### Observation

The first semgrep output shows that the implicit Intent usage in the code (e.g., `Intent.setAction(...)`, then starts activity with `startActivity`.

The second semgrep output shows that `org.owasp.mastestapp.VulnerableActivity` is an exported activity declared in the `AndroidManifest.xml`. It contains an `<intent-filter>` block that registers a custom action.

### Evaluation

The test fails because of presence of both an implicit intent usage in the code and an exported activity with a matching action confirms a vulnerability in the component that can be exploited by attacker application.
13 changes: 13 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0043/output1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@


┌────────────────┐
│ 1 Code Finding │
└────────────────┘

MastgTest_reversed.java
❯❱ mastg-android-implicit-intent-start-activity
[MASVS-CODE] Use implicit Intent with startActivity carefully to avoid exposing exported components

28┆ Intent intent = new Intent();
29┆ intent.setAction("org.owasp.mastestapp.VULNERABLE_ACTION");
30┆ this.context.startActivity(intent);
25 changes: 25 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0043/output2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@


┌─────────────────┐
│ 2 Code Findings │
└─────────────────┘

AndroidManifest_reversed.xml
❯❱ mastg-android-exported-activity-with-intent-filter
[MASVS-CODE] An exported activity with an intent-filter may be at risk of implicit intent
exploitation

6┆ <activity android:exported="true" android:name="org.owasp.mastestapp.MainActivity"
android:theme="@style/Theme.MASTestApp">
7┆ <intent-filter>
8┆ <action android:name="android.intent.action.MAIN"/>
9┆ <category android:name="android.intent.category.LAUNCHER"/>
10┆ </intent-filter>
11┆ </activity>
⋮┆----------------------------------------
12┆ <activity android:exported="true" android:name="org.owasp.mastestapp.VulnerableActivity">
&gt; <intent-filter>
13┆ <action android:name="org.owasp.mastestapp.VULNERABLE_ACTION"/>
14┆ <category android:name="android.intent.category.DEFAULT"/>
15┆ </intent-filter>
16┆ </activity>
2 changes: 2 additions & 0 deletions demos/android/MASVS-CODE/MASTG-DEMO-0043/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-implicit-intent-start-activity.yml ../MASTG-DEMO-0042/MastgTest_reversed.java --text -o output1.txt
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-implicit-exported-activity.yml ../MASTG-DEMO-0042/AndroidManifest_reversed.xml --text -o output2.txt
17 changes: 17 additions & 0 deletions rules/mastg-android-exported-activity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
rules:
- id: mastg-android-exported-activity-with-intent-filter
severity: WARNING
languages:
- xml
metadata:
summary: The rule looks for exported activity with intent-filter
message: "[MASVS-CODE] An exported activity with an intent-filter may be at risk of implicit intent exploitation"
patterns:
- pattern: |
<activity android:exported="true" android:name="$ACTIVITY">
...
<intent-filter>
<action android:name="$ACTION" />
...
</intent-filter>
</activity>
18 changes: 18 additions & 0 deletions rules/mastg-android-implicit-intent-start-activity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
rules:
- id: mastg-android-implicit-intent-start-activity
severity: WARNING
languages:
- java
metadata:
summary: The rule checks if the implicit Intent is used to start any activity without specifying the target component
message: "[MASVS-CODE] Use implicit Intent with startActivity carefully to avoid exposing exported components"
pattern-either:
- pattern: |
Intent $INTENT = new Intent("$ACTION");
...
startActivity($INTENT);
- pattern: |
Intent $INTENT = new Intent();
$INTENT.setAction("$ACTION");
...
$OBJ.startActivity($INTENT);
24 changes: 24 additions & 0 deletions tests-beta/android/MASVS-CODE/MASTG-TEST-0026.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
title: Implicit intent to trigger internal app components
platform: android
id: MASTG-TEST-0026
type: [dynamic]
weakness: MASWE-0083
---

## Overview

Android enables communication between its components through intents, which serve as messaging objects to request actions from other application components. Intents can be explicit, targeting a specific component, or implicit, where the system identifies the suitable component based on the intent's action, data, or category. When you declare an internal component, like an Activity, with `android:exported="true"` and link it to an `<intent-filter>`, it becomes available to external applications via implicit intents. This can introduce security vulnerabilities if the component handles sensitive tasks or accepts input from the intent without proper validation. An attacker might create a malicious app to activate these exported components, potentially altering application behavior or accessing sensitive data.

## Steps

1. Install the attacker app on a device @MASTG-TECH-0004.
2. Press the button to trigger the malicious intent.

## Observation

The attacker's application was able to successfully launch the VulnerableActivity using an crafted intent.

## Evaluation

The test fails due to the exported activity being accessible via an implicit intent.
23 changes: 23 additions & 0 deletions tests-beta/android/MASVS-CODE/MASTG-TEST-0027.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Implicit intent to trigger internal app components
platform: android
id: MASTG-TEST-0027
type: [static]
weakness: MASWE-0083
---

## Overview

Android enables communication between its components through intents, which serve as messaging objects to request actions from other application components. Intents can be explicit, targeting a specific component, or implicit, where the system identifies the suitable component based on the intent's action, data, or category. When you declare an internal component, like an Activity, with `android:exported="true"` and link it to an `<intent-filter>`, it becomes available to external applications via implicit intents. This can introduce security vulnerabilities if the component handles sensitive tasks or accepts input from the intent without proper validation. An attacker might create a malicious app to activate these exported components, potentially altering application behavior or accessing sensitive data.

## Steps

1. Run a static analysis tool such as @MASTG-TOOL-0110 on the code and `AndroidManifest.xml` file.

## Observation

The code uses an implicit intent by setting an action via `Intent.setAction()` and launching it with `startActivity()`. Also, `AndroidManifest.xml` declares an exported activity with an intent filter that matches the custom action.

## Evaluation

The test fails due to the exported activity being accessible via an implicit intent.
2 changes: 2 additions & 0 deletions tests/android/MASVS-CODE/MASTG-TEST-0026.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ title: Testing Implicit Intents
masvs_v1_levels:
- L1
- L2
status: deprecated
deprecation_note: New version available in MASTG V2
---

## Overview
Expand Down