diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MASTG-DEMO-0081.md b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MASTG-DEMO-0081.md new file mode 100644 index 0000000000..95fde9b9fb --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MASTG-DEMO-0081.md @@ -0,0 +1,39 @@ +--- +platform: android +title: Sensitive User Data Sent to Firebase Analytics with Frida +id: MASTG-DEMO-0081 +code: [kotlin] +test: MASTG-TEST-0319 +--- + +## Sample + +This sample collects the following [sensitive user data](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en#types&zippy=%2Cdata-types) and sends it to Firebase Analytics using the `logEvent` method: + +- User ID (**Data type:** User IDs, **Category:** Personal info) +- Blood type (**Data type:** Health info, **Category:** Health and fitness) + +For the sake of this demo, we pretend that the app is published on Google Play and that the data types collected are not disclosed in the [Data safety section](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en#types&zippy=%2Cdata-types). + +{{ MainActivity.kt # MastgTest.kt # build.gradle.kts.libs }} + +## Steps + +1. Install the app on a device (@MASTG-TECH-0005) +2. Make sure you have @MASTG-TOOL-0001 installed on your machine and the frida-server running on the device +3. Run `run.sh` to spawn the app with Frida +4. Select a blood type from the dropdown +5. Click the **Start** button +6. Stop the script by pressing `Ctrl+C` and/or `q` to quit the Frida CLI + +{{ hooks.js # run.sh }} + +## Observation + +The output shows all instances of `logEvent` calls to the Firebase Analytics SDK found at runtime, along with the parameters sent. A backtrace is also provided to help identify the location in the code. + +{{ output.json }} + +## Evaluation + +This test **fails** because sensitive data (`blood_type` parameter) is being sent to Firebase Analytics via the `logEvent` method for a particular user (`user_id` parameter) and this data collection is not disclosed in the Data safety section on Google Play (as we indicated in the sample description). diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MainActivity.kt b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MainActivity.kt new file mode 100644 index 0000000000..36555f72a9 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MainActivity.kt @@ -0,0 +1,158 @@ +package org.owasp.mastestapp + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.decodeFromJsonElement + +const val MASTG_TEXT_TAG = "mastgTestText" + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + MainScreen() + } + } +} + +fun UpdateDisplayString( + defaultMessage: String, + result: String +): AnnotatedString { + return buildAnnotatedString { + append(defaultMessage) + try { + val jsonArrayFromString = Json.parseToJsonElement(result) as JsonArray + val demoResults = jsonArrayFromString.map { Json.decodeFromJsonElement(it) } + + for (demoResult in demoResults) { + when (demoResult.status) { + Status.PASS -> { + withStyle(style = SpanStyle(color = Color.Green)) { + append("MASTG-DEMO-${demoResult.demoId} demonstrated a successful test:\n${demoResult.message}\n\n") + } + } + + Status.FAIL -> { + withStyle(style = SpanStyle(color = Color(0xFFFF9800))) { + append("MASTG-DEMO-${demoResult.demoId} demonstrated a failed test:\n${demoResult.message}\n\n") + } + } + + Status.ERROR -> { + withStyle(style = SpanStyle(color = Color.Red)) { + append("MASTG-DEMO-${demoResult.demoId} failed:\n${demoResult.message}\n\n") + } + } + } + } + } catch (_: Exception) { + // not a valid set of DemoResult, so print the result without any parsing + append(result) + } + } + +} + +@Preview +@Composable +fun MainScreen() { + val defaultMessage = "Click \"Start\" to send the data.\n\n" + var displayString by remember { mutableStateOf(buildAnnotatedString { append(defaultMessage) }) } + var selectedBloodType by remember { mutableStateOf("") } + val context = LocalContext.current + val mastgTestClass = MastgTest(context) + // By default run the test in a separate thread, this ensures that network tests such as those using SSLSocket work properly. + // However, some tests which interact with UI elements need to run on the main thread. + // You can set shouldRunInMainThread = true in MastgTest.kt for those tests. + val runInMainThread = MastgTest::class.members + .find { it.name == "shouldRunInMainThread" } + ?.call(mastgTestClass) as? Boolean ?: false + + BaseScreen( + onStartClick = { + if (runInMainThread) { + val result = mastgTestClass.mastgTest(selectedBloodType) + displayString = UpdateDisplayString(defaultMessage, result) + } else { + Thread { + val result = mastgTestClass.mastgTest(selectedBloodType) + android.os.Handler(android.os.Looper.getMainLooper()).post { + displayString = UpdateDisplayString(defaultMessage, result) + } + }.start() + } + } + ) { + Column(modifier = Modifier.padding(16.dp)) { + // Normal visible selection UI: list of radio buttons for blood types + val bloodTypes = listOf("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-") + + var expanded by remember { mutableStateOf(false) } + + Button(onClick = { expanded = !expanded }) { + Text("Select Blood Type") + } + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false } + ) { + bloodTypes.forEach { + DropdownMenuItem( + text = { Text(it) }, + onClick = { + selectedBloodType = it + expanded = false + } + ) + } + } + + if (selectedBloodType.isNotEmpty()) { + Text( + modifier = Modifier.padding(vertical = 16.dp), + color = Color.White, + text = "Selected Blood Type: $selectedBloodType" + ) + } + + Text( + modifier = Modifier + .padding(top = 8.dp) + .testTag(MASTG_TEXT_TAG), + text = displayString, + color = Color.White, + fontSize = 16.sp, + fontFamily = FontFamily.Monospace + ) + } + } +} diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MastgTest.kt b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MastgTest.kt new file mode 100644 index 0000000000..6a50404a94 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/MastgTest.kt @@ -0,0 +1,28 @@ +package org.owasp.mastestapp + +import android.content.Context +import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.analytics.logEvent +import kotlin.random.Random + +class MastgTest(context: Context) { + + val analytics = FirebaseAnalytics.getInstance(context) + + // Random arbitrary number for the sake of the demo + val userId: String = (1..8).map { Random.nextInt(0, 10) }.joinToString("") + + fun mastgTest(bloodType: String): String { + analytics.logEvent("user_blood_type") { + param("user_id", userId) + param("blood_type", bloodType) + } + + return """ + 'user_blood_type' event was sent to Firebase Analytics. + + User id: $userId + Blood type: $bloodType + """.trimIndent() + } +} \ No newline at end of file diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/after.png b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/after.png new file mode 100644 index 0000000000..d68c48d7ef Binary files /dev/null and b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/after.png differ diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/auto.log b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/auto.log new file mode 100644 index 0000000000..6548e60d32 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/auto.log @@ -0,0 +1,7 @@ +Running on Pixel_4_API_34_Manually_Created + > Flow flow +Take screenshot before... COMPLETED +Tap on "Select Blood Type"... COMPLETED +Tap on "A+"... COMPLETED +Tap on "Start"... COMPLETED +Take screenshot after... COMPLETED diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/auto.sh b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/auto.sh new file mode 100755 index 0000000000..d943434383 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/auto.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +FLOW="flow.yaml" + +# Start Frida and redirect stdout and stderr to file +./run.sh 2>&1 & + +FRIDA_PID=$! + +# Run Maestro (https://docs.maestro.dev/getting-started/installing-maestro) +maestro test "$FLOW" > auto.log 2>&1 +MAESTRO_EXIT=$? + +# Stop Frida when Maestro completes +kill "$FRIDA_PID" 2>/dev/null || true + +exit "$MAESTRO_EXIT" diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/before.png b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/before.png new file mode 100644 index 0000000000..8079f70b93 Binary files /dev/null and b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/before.png differ diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/build.gradle.kts.libs b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/build.gradle.kts.libs new file mode 100644 index 0000000000..04a6e7c777 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/build.gradle.kts.libs @@ -0,0 +1 @@ +implementation("com.google.firebase:firebase-analytics:23.0.0") \ No newline at end of file diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/flow.yaml b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/flow.yaml new file mode 100644 index 0000000000..671509d314 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/flow.yaml @@ -0,0 +1,8 @@ +appId: org.owasp.mastestapp +--- +#- launchApp +- takeScreenshot: before +- tapOn: "Select Blood Type" +- tapOn: "A+" +- tapOn: "Start" +- takeScreenshot: after \ No newline at end of file diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/hooks.js b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/hooks.js new file mode 100644 index 0000000000..c3551f80b5 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/hooks.js @@ -0,0 +1,11 @@ +var target = { + category: "PRIVACY", + hooks: [ + { + class: "com.google.firebase.analytics.FirebaseAnalytics", + methods: [ + "logEvent" + ] + } + ] +} diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/output.json b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/output.json new file mode 100644 index 0000000000..72a5ae4266 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/output.json @@ -0,0 +1,56 @@ +{ + "type": "summary", + "hooks": [ + { + "class": "com.google.firebase.analytics.FirebaseAnalytics", + "method": "logEvent", + "overloads": [ + { + "args": [ + "java.lang.String", + "android.os.Bundle" + ] + } + ] + } + ], + "totalHooks": 1, + "errors": [], + "totalErrors": 0 +} +{ + "id": "68f13e77-c2aa-4778-be90-fc7a5c50af60", + "type": "hook", + "category": "PRIVACY", + "time": "2025-12-04T14:03:05.046Z", + "class": "com.google.firebase.analytics.FirebaseAnalytics", + "method": "logEvent", + "instanceId": 33276343, + "stackTrace": [ + "com.google.firebase.analytics.FirebaseAnalytics.logEvent(Native Method)", + "org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:35)", + "org.owasp.mastestapp.MainActivityKt.MainScreen$lambda$15$lambda$14(MainActivity.kt:107)", + "org.owasp.mastestapp.MainActivityKt.$r8$lambda$REihytfpbfdEl1cb3dLDlSFXk5M(Unknown Source:0)", + "org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda2.run(D8$$SyntheticClass:0)", + "java.lang.Thread.run(Thread.java:1119)" + ], + "inputParameters": [ + { + "declaredType": "java.lang.String", + "value": "user_blood_type" + }, + { + "declaredType": "android.os.Bundle", + "value": "", + "runtimeType": "android.os.Bundle", + "instanceId": "130116900", + "instanceToString": "Bundle[{blood_type=A+, user_id=87495975}]" + } + ], + "returnValue": [ + { + "declaredType": "void", + "value": "void" + } + ] +} diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/run.sh b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/run.sh new file mode 100755 index 0000000000..3b78c35a81 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0081/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +../../../../utils/frida/android/run.sh ./hooks.js diff --git a/techniques/android/MASTG-TECH-0108.md b/techniques/android/MASTG-TECH-0108.md index f60ef3a541..c881b3515e 100644 --- a/techniques/android/MASTG-TECH-0108.md +++ b/techniques/android/MASTG-TECH-0108.md @@ -9,13 +9,13 @@ In taint analysis, data flows from a "source" to a "sink". A source is where sen In large applications, manual information flow analysis can be very time-consuming and inaccurate. Taint analysis automates this, with two main methods: static and dynamic. The former examines code without running it, offering broad coverage but potentially yielding false positives. In contrast, dynamic analysis observes real-time application execution, providing actual context but possibly overlooking untriggered issues. A thorough comparison of these techniques is beyond this section's scope. -There are multiple tools which perform taint analysis on native code, including [Triton](https://github.com/jonathansalwan/Triton "Triton") and [bincat](https://github.com/airbus-seclab/bincat "bincat"). However, in this section, we'll primarily focus on Android Java code and utilize @MASTG-TOOL-0099 for the taint analysis. Another notable tool supporting taint analysis for Android apps is [GDA](https://github.com/charles2gan/GDA-android-reversing-Tool/wiki/GDA-Static-Taint-Analysis "GDA"). +There are multiple tools which perform taint analysis on native code, including [Triton](https://github.com/jonathansalwan/Triton "Triton"), [bincat](https://github.com/airbus-seclab/bincat "bincat"), and @MASTG-TOOL-0110. However, in this section, we'll primarily focus on Android Java code and utilize @MASTG-TOOL-0099 for the taint analysis. Another notable tool supporting taint analysis for Android apps is [GDA](https://github.com/charles2gan/GDA-android-reversing-Tool/wiki/GDA-Static-Taint-Analysis "GDA"). For our demonstration, we'll use the @MASTG-TOOL-0099 command line tool to perform taint analysis on the [InsecureShop v1.0](https://github.com/hax0rgb/InsecureShop/releases/tag/v1.0 "InsecureShop") application. The InsecureShop app accepts a username and password as input and stores them in the app's shared preferences. In our taint analysis, we're interested in how this stored username and password are used. In this context, the username and password are the sensitive information, and reading from shared preferences is the source. The sink in this analysis could be various operations, such as sending info over the network, transmitting info via an `Intent`, or storing info in an external file. -To use FlowDroid, firstly, we need to provide an input list of potential sources and sinks to evaluate for. In our case, _reading from shared preferences_ will be the source, while _adding parameters to an `Intent`_ will be the sink. The configuration file will look as follows (we'll name it "source_sink.txt"): +To use FlowDroid, firstly, we need to provide an input list of potential sources and sinks to evaluate. In our case, _reading from shared preferences_ will be the source, while _adding parameters to an `Intent`_ will be the sink. The configuration file will look as follows (we'll name it "source_sink.txt"): ```Jimple -> _SOURCE_ @@ -68,4 +68,4 @@ fun onSendData(view: View) { } ``` -Taint analysis is especially beneficial for automating data flow analysis in intricate applications. However, given the complexity of some apps, the accuracy of such tools can vary. Thus, it's essential for reviewers to find a balance between the accuracy of tools and the time spent on manual analysis. +Taint analysis is especially beneficial for automating data flow analysis in intricate applications. However, given the complexity of some apps, the accuracy of such tools can vary. Thus, reviewers need to find a balance between the accuracy of tools and the time spent on manual analysis. diff --git a/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0206.md b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0206.md index 9b6540d58b..ce1813b42d 100644 --- a/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0206.md +++ b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0206.md @@ -31,4 +31,4 @@ The output should contain a network traffic log that includes the decrypted HTTP The test case fails if you can find the PII you entered in the app that is not declared in the app's marketplace privacy declarations (e.g., Data Safety section in Google Play) and/or in its privacy policy. -Note that this test does not provide any code locations where the sensitive data is being sent over the network. In order to identify the code locations, you can use static analysis tools like @MASTG-TOOL-0110 or dynamic analysis tools like @MASTG-TOOL-0031. +Note that this test does not provide any code locations where the sensitive data is being sent over the network. In order to identify the code locations, you can use static analysis tools like @MASTG-TOOL-0110 or dynamic analysis tools like @MASTG-TOOL-0031. Consult @MASTG-TEST-0318 and @MASTG-TEST-0319, respectively, for more details. diff --git a/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0318.md b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0318.md new file mode 100644 index 0000000000..1aa5835d71 --- /dev/null +++ b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0318.md @@ -0,0 +1,29 @@ +--- +platform: android +title: References to SDK APIs Known to Handle Sensitive User Data +id: MASTG-TEST-0318 +type: [static] +weakness: MASWE-0112 +profiles: [P] +--- + +## Overview + +This test verifies whether an app uses SDK (third-party library) APIs known to handle sensitive user data (e.g., as defined in [Google Play's Data safety section](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en#types&zippy=%2Cdata-types) or the relevant privacy regulations). + +As a prerequisite, we need to identify the SDK API methods it uses as entry points for data collection by reviewing the library's documentation or codebase. For example, [Google Analytics for Firebase](https://firebase.google.com/docs/analytics) in its class `FirebaseAnalytics` provides methods such as [`setUserId`](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics#setUserId(java.lang.String)), [`setUserProperty`](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics#setUserProperty(java.lang.String,%20java.lang.String)), and [`logEvent`](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics#logEvent(java.lang.String,%20android.os.Bundle)) that can be used to collect user data. + +> Note: This test detects only **potential** sensitive user data handling. For **confirming** that actual user data are being shared, please refer to @MASTG-TEST-0319. + +## Steps + +1. Use @MASTG-TECH-0013 to reverse engineer the app. +2. Use @MASTG-TECH-0014 to look for uses of these methods where sensitive user data may be passed to the SDK. + +## Observation + +The output should list the locations where SDK methods are called. + +## Evaluation + +The test case fails if you can find the use of these SDK methods in the app code, indicating that the app is sharing sensitive user data with the third-party SDK. If no such references are found, the test case passes. diff --git a/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0319.md b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0319.md new file mode 100644 index 0000000000..f32d19d4c7 --- /dev/null +++ b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0319.md @@ -0,0 +1,26 @@ +--- +platform: android +title: Runtime Use of SDK APIs Known to Handle Sensitive User Data +id: MASTG-TEST-0319 +type: [dynamic] +weakness: MASWE-0112 +prerequisites: + - identify-sensitive-data +profiles: [P] +--- + +## Overview + +This test is the dynamic counterpart to @MASTG-TEST-0318. + +## Steps + +1. Use @MASTG-TECH-0033 to hook SDK methods known to handle sensitive user data. + +## Observation + +The output should list the locations where SDK methods are called, their stacktrace (call hierarchy leading to the call), and the arguments (values) passed to the SDK method at runtime. + +## Evaluation + +The test case fails if you can find sensitive user data being passed to these SDK methods in the app code, indicating that the app is sharing sensitive user data with the third-party SDK. If no such data sharing is found, the test case passes. diff --git a/tests/android/MASVS-STORAGE/MASTG-TEST-0004.md b/tests/android/MASVS-STORAGE/MASTG-TEST-0004.md index 5ef713be31..f69fb60fd9 100644 --- a/tests/android/MASVS-STORAGE/MASTG-TEST-0004.md +++ b/tests/android/MASVS-STORAGE/MASTG-TEST-0004.md @@ -4,23 +4,25 @@ masvs_v1_id: masvs_v2_id: - MASVS-STORAGE-2 platform: android -title: Determining Whether Sensitive Data Is Shared with Third Parties via Embedded - Services +title: Determining Whether Sensitive Data Is Shared with Third Parties via Embedded Services masvs_v1_levels: - L1 - L2 profiles: [L1, L2] +status: deprecated +covered_by: [MASTG-TEST-0318, MASTG-TEST-0319] +deprecation_note: New version available in MASTG V2 --- ## Overview ## Static Analysis -To determine whether API calls and functions provided by the third-party library are used according to best practices, review their source code, requested permissions and check for any known vulnerabilities. +To determine whether API calls and functions provided by the third-party library are used according to best practices, review their source code, requested permissions, and check for any known vulnerabilities. All data that's sent to third-party services should be anonymized to prevent exposure of PII (Personal Identifiable Information) that would allow the third party to identify the user account. No other data (such as IDs that can be mapped to a user account or session) should be sent to a third party. ## Dynamic Analysis Check all requests to external services for embedded sensitive information. -To intercept traffic between the client and server, you can perform dynamic analysis by launching a [Machine-in-the-Middle (MITM)](../../../Document/0x04f-Testing-Network-Communication.md#intercepting-network-traffic-through-mitm) attack with @MASTG-TOOL-0077 or @MASTG-TOOL-0079. Once you route the traffic through the interception proxy, you can try to sniff the traffic that passes between the app and server. All app requests that aren't sent directly to the server on which the main function is hosted should be checked for sensitive information, such as PII in a tracker or ad service. +To intercept traffic between the client and server, you can perform dynamic analysis by launching a [Machine-in-the-Middle (MITM)](../../../Document/0x04f-Testing-Network-Communication.md#intercepting-network-traffic-through-mitm) attack with @MASTG-TOOL-0077 or @MASTG-TOOL-0079. Once you route the traffic through the interception proxy, you can try to sniff the traffic that passes between the app and server. All app requests that aren't sent directly to the server on which the main function is hosted should be checked for sensitive information, such as PII, in a tracker or ad service.