Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0cdcd45
Deprecate old test
Diolor Sep 24, 2025
536aacb
Add mitmproxy in TECH-0108
Diolor Sep 26, 2025
525a75e
Create the v2 TEST
Diolor Sep 26, 2025
ea8e1ed
Create a demo based on the test
Diolor Sep 26, 2025
31d6209
Fix lint
Diolor Sep 26, 2025
52d0619
Fix lint
Diolor Sep 26, 2025
99e15f8
Fix lint
Diolor Sep 26, 2025
a12122a
Fix lint
Diolor Sep 26, 2025
4618723
Remove prerequisite
Diolor Sep 29, 2025
13118f7
Rewrite test to include frida
Diolor Oct 1, 2025
ff3bf25
Move to Privacy
Diolor Oct 2, 2025
a45c42f
Move Firebase Analytics dependency
Diolor Oct 6, 2025
ccb8c1c
Move Firebase Analytics dependency
Diolor Oct 6, 2025
2037585
Update title to clarify sensitive information exposure in Firebase An…
Diolor Oct 6, 2025
7e4ecf2
Allocate IDs
Diolor Oct 20, 2025
9078204
Merge remote-tracking branch 'origin/master' into port-MASTG-TEST-0004
Diolor Oct 20, 2025
fab5dea
Allocate IDs
Diolor Oct 20, 2025
4351d41
Update weakness reference in MASTG-TEST-0297.md
Diolor Nov 17, 2025
625d6b3
Merge branch 'master' into port-MASTG-TEST-0004
cpholguera Dec 3, 2025
dc4e504
Merge branch 'master' into port-MASTG-TEST-0004
cpholguera Dec 3, 2025
2e7adb8
Split test into 4 smaller tests.
Diolor Dec 4, 2025
1d02dae
Fix id
Diolor Dec 4, 2025
4dea6df
Add demo for dynamic evaluation of sensitive data in runtime
Diolor Dec 4, 2025
0bc53db
Update demos/android/MASVS-PRIVACY/MASTG-DEMO-00de3/hooks.js
Diolor Dec 5, 2025
1183269
Apply suggestions from code review
Diolor Dec 5, 2025
64fcf89
Update references in MASTG-TEST-02te4.md and MASTG-TEST-0004.md
Diolor Dec 5, 2025
af21b06
Apply suggestions from code review
Diolor Dec 9, 2025
f91db2e
add UI automation
cpholguera Dec 9, 2025
5aae326
Merge branch 'master' into port-MASTG-TEST-0004
Diolor Dec 16, 2025
b088cdd
Remove MASTG-DEMO-00de1
Diolor Dec 17, 2025
b3f7659
Refine documentation for SDK method observations and data handling tests
Diolor Dec 17, 2025
2c5e4bd
Moved to #3595
Diolor Dec 17, 2025
57a91ab
correct output
cpholguera Dec 18, 2025
f638528
Last set of minor tweaks including title updates, links to data safet…
cpholguera Dec 18, 2025
3d7ee2e
fix IDs
cpholguera Dec 18, 2025
8b5aca8
Merge branch 'master' into port-MASTG-TEST-0004
cpholguera Dec 18, 2025
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
33 changes: 33 additions & 0 deletions demos/android/MASVS-PLATFORM/MASTG-DEMO-yyyy/MASTG-DEMO-yyyy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
platform: android
title: App leaking sensitive information to Firebase Analytics
id: MASTG-DEMO-yyyy
code: [kotlin]
test: MASTG-TEST-xxxx
---

## Sample

This sample demonstrates an Android application that inadvertently leaks sensitive user information to Firebase Analytics. The app collects various types of sensitive data, such as user IDs, email addresses, and names, and sends this information to Firebase Analytics.

> Note: To compile the test correctly, you need to include the Firebase Analytics library in the `build.gradle` file. i.e.`implementation("com.google.firebase:firebase-analytics:23.0.0")`.

{{ MastgTest.kt }}

## Steps

Let's run our @MASTG-TOOL-0110 rule against the reversed Java code.

{{ ../../../../rules/mastg-android-sensitive-data-to-embedded-firebase-analytics.yml }}

{{ run.sh }}

## Observation

The rule detected 8 instances where sensitive data might be sent to Firebase Analytics. The findings include various types of sensitive information, such as user IDs, email addresses, and names, based on the rule's defined pattern.

{{ output.txt }}

## Evaluation

After reviewing the decompiled code at the location specified in the output (file and line number), we can conclude that the test fails because the file written by this instance contains sensitive information, specifically a first and a last name, an email, a user ID, and a secret.
46 changes: 46 additions & 0 deletions demos/android/MASVS-PLATFORM/MASTG-DEMO-yyyy/MastgTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.owasp.mastestapp

import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics

class MastgTest(private val context: Context) {

fun mastgTest(): String {
val sensitiveString = "d3a447630194bd4b"
val email = "user@example.com"
val firstLast = "John Doe"
val arbitraryUserId = "user12345"

val analytics = FirebaseAnalytics.getInstance(context)

// Test 1: logEvent with bundle
val eventBundle = Bundle().apply {
putString("user_email", email)
putString("full_name", firstLast)
}
analytics.logEvent("event_name", eventBundle)

// Test 2: setUserProperty
analytics.apply {
setUserProperty("name", firstLast)
setUserProperty("email", email)
}

// Test 3: setUserId
analytics.setUserId(arbitraryUserId)

// Test 4: setDefaultEventParameters
val defaultBundle = Bundle().apply {
putString("default_key", sensitiveString)
}
analytics.setDefaultEventParameters(defaultBundle)

return """Sensitive data:
Email: $email
Full Name: $firstLast
User ID: $arbitraryUserId
Sensitive String: $sensitiveString
""".trimIndent()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.owasp.mastestapp;

import android.content.Context;
import android.os.Bundle;
import com.google.firebase.analytics.FirebaseAnalytics;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import kotlin.text.StringsKt;

/* compiled from: MastgTest.kt */
@Metadata(d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u000e\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\u0007R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\b"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "<init>", "(Landroid/content/Context;)V", "mastgTest", "", "app_debug"}, k = 1, mv = {2, 0, 0}, xi = 48)
/* loaded from: classes3.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() {
FirebaseAnalytics analytics = FirebaseAnalytics.getInstance(this.context);
Intrinsics.checkNotNullExpressionValue(analytics, "getInstance(...)");
Bundle eventBundle = new Bundle();
eventBundle.putString("user_email", "user@example.com");
eventBundle.putString("full_name", "John Doe");
analytics.logEvent("event_name", eventBundle);
analytics.setUserProperty("name", "John Doe");
analytics.setUserProperty("email", "user@example.com");
analytics.setUserId("user12345");
Bundle defaultBundle = new Bundle();
defaultBundle.putString("default_key", "d3a447630194bd4b");
analytics.setDefaultEventParameters(defaultBundle);
return StringsKt.trimIndent("Sensitive data:\n\t\t\tEmail: user@example.com\n\t\t\tFull Name: John Doe\n\t\t\tUser ID: user12345\n\t\t\tSensitive String: d3a447630194bd4b\n\t\t\t");
}
}
26 changes: 26 additions & 0 deletions demos/android/MASVS-PLATFORM/MASTG-DEMO-yyyy/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@


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

MastgTest_reversed.java
❯❱ rules.mastg-android-sensitive-data-to-embedded-firebase-analytics
[MASVS-PLATFORM-2] Sensitive data is being sent to Firebase Analytics

26┆ eventBundle.putString("user_email", "user@example.com");
⋮┆----------------------------------------
27┆ eventBundle.putString("full_name", "John Doe");
⋮┆----------------------------------------
28┆ analytics.logEvent("event_name", eventBundle);
⋮┆----------------------------------------
29┆ analytics.setUserProperty("name", "John Doe");
⋮┆----------------------------------------
30┆ analytics.setUserProperty("email", "user@example.com");
⋮┆----------------------------------------
31┆ analytics.setUserId("user12345");
⋮┆----------------------------------------
33┆ defaultBundle.putString("default_key", "d3a447630194bd4b");
⋮┆----------------------------------------
34┆ analytics.setDefaultEventParameters(defaultBundle);

1 change: 1 addition & 0 deletions demos/android/MASVS-PLATFORM/MASTG-DEMO-yyyy/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-sensitive-data-to-embedded-firebase-analytics.yml ./MastgTest_reversed.java > output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
rules:
- id: mastg-android-sensitive-data-to-embedded-firebase-analytics
severity: WARNING
languages: [java]
metadata:
summary: "Detects sensitive data being sent to Firebase Analytics."
message: "[MASVS-PLATFORM-2] Sensitive data is being sent to Firebase Analytics"
mode: taint
pattern-sources:
- patterns:
- pattern: '"$SECRET"'
- metavariable-analysis:
metavariable: $SECRET
analyzer: entropy
- patterns:
- pattern: '"$EMAIL"'
- metavariable-regex:
metavariable: $EMAIL
regex: (?i)[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}
- patterns:
- pattern: '"$FULLNAME"'
- metavariable-regex:
metavariable: $FULLNAME
regex: (?i)[A-Z][a-z]+ [A-Z][a-z]+
- patterns:
- pattern: '"$UID"'
- metavariable-regex:
metavariable: $UID
regex: (?i)user[0-9]+
pattern-sinks:
- pattern: $FA.logEvent($EVT, $ARG)
- pattern: $FA.setUserProperty($NAME, $ARG)
- pattern: $FA.setUserId($ARG)
- pattern: $FA.setDefaultEventParameters($ARG)
- pattern: $BUNDLE.putString($K, $V)
pattern-inside: |
...;
$FA.logEvent($EVT, $BUNDLE);
...;
pattern-propagators:
- pattern: $BUNDLE.putString($K, $V)
from: $V
to: $BUNDLE
6 changes: 3 additions & 3 deletions techniques/android/MASTG-TECH-0108.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<android.content.SharedPreferences: java.lang.String getString(java.lang.String, java.lang.String)> -> _SOURCE_
Expand Down Expand Up @@ -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.
35 changes: 35 additions & 0 deletions tests-beta/android/MASVS-PLATFORM/MASTG-TEST-xxxx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
platform: android
title: Sensitive Data Leaked via Embedded Libraries
id: MASTG-TEST-xxxx // TODO
type: [static, dynamic]
weakness: MASWE-xxxA // TODO see https://github.com/OWASP/maswe/pull/11
prerequisites:
- identify-sensitive-data
- identify-embedded-libraries-with-network-access // TODO makes sense? get feedback
Comment thread
Diolor marked this conversation as resolved.
Outdated
profiles: [L1, L2]
---

## Overview

This test case focuses on identifying potentially sensitive data inadvertently leaked through embedded third-party libraries used by the application. For example, an app might use a third-party analytics SDK to track user behavior, but if the SDK is not properly configured, it could inadvertently send sensitive information (like PIIs - Personal Identifiable Information, or secrets) to that third-party service.

## Steps

1. Generate an SBOM.
- For black-box testing, you can use tools like @MASTG-TOOL-0130 or @MASTG-TOOL-0134 with @MASG-TECH-0130 or @MASTG-TECH-0131 to identify all embedded/3rd-party libraries used by the app.
- For grey/white-box testing, you can manually review the app's build files (like `build.gradle`) to identify dependencies.
2. Shortlist the embedded/3rd-party libraries' APIs which have network functionality and that should not handle sensitive information. Look for permissions like `INTERNET` or `ACCESS_NETWORK_STATE`.
- For black-box testing, you can research those libraries online or their codebase to see if they have network functionality.
- For gray/white-box testing, you can manually review the app's merged manifest file in Android Studio or by manually generating with a command like `./gradlew app:processDebugManifest` and then inspecting the file in `app/build/intermediates/merged_manifests/debug/AndroidManifest.xml`. If possible, you can review the app's codebase.
Comment thread
Diolor marked this conversation as resolved.
Outdated
3. Identify common APIs of those libraries that are used to send data to their servers.
- Use @MASTG-TECH-0110, potentially with @MASTG-TOOL-0108, to identify sensitive data pass to the APIs.
- Alternatively use you can perform dynamic analysis by intercepting traffic using @MASTG-TECH-0120 and @MASTG-TECH-0121. Once you route the traffic through the interception proxy, you can try to sniff the traffic that passes between the app and app's known servers. All app requests that aren't sent directly to the app's server on which the main function is hosted should be evaluated.
Comment thread
cpholguera marked this conversation as resolved.
Outdated

## Observation

The output should contain a list of locations where sensitive information is passed to embedded/3rd-party libraries or a list of network requests to third-party servers that contain sensitive information.

## Evaluation

The test case fails if sensitive data is found to be passed to embedded/3rd-party libraries that have network functionality or if network requests to third-party servers contain sensitive information.
10 changes: 6 additions & 4 deletions tests/android/MASVS-STORAGE/MASTG-TEST-0004.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-xxxx] // TODO
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.
Loading