diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MASTG-DEMO-0066.md b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MASTG-DEMO-0066.md new file mode 100644 index 00000000000..020194a8c95 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MASTG-DEMO-0066.md @@ -0,0 +1,31 @@ +--- +platform: android +title: App Exposing Sensitive Information to Firebase Analytics +id: MASTG-DEMO-0066 +code: [kotlin] +test: MASTG-TEST-0297 +--- + +## 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. + +{{ MastgTest.kt # build.gradle.kts.libs }} + +## 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. diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MastgTest.kt b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MastgTest.kt new file mode 100644 index 00000000000..714a4e24ce1 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MastgTest.kt @@ -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() + } +} \ No newline at end of file diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MastgTest_reversed.java b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MastgTest_reversed.java new file mode 100644 index 00000000000..41ca3e8d310 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/MastgTest_reversed.java @@ -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;", "", "(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"); + } +} diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/build.gradle.kts.libs b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/build.gradle.kts.libs new file mode 100644 index 00000000000..04a6e7c7779 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/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-0066/output.txt b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/output.txt new file mode 100644 index 00000000000..4fc0c3b21f9 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/output.txt @@ -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); + diff --git a/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/run.sh b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/run.sh new file mode 100755 index 00000000000..e3c13da7f96 --- /dev/null +++ b/demos/android/MASVS-PRIVACY/MASTG-DEMO-0066/run.sh @@ -0,0 +1 @@ +NO_COLOR=true semgrep -c ../../../../rules/mastg-android-sensitive-data-to-embedded-firebase-analytics.yml ./MastgTest_reversed.java > output.txt diff --git a/rules/mastg-android-sensitive-data-to-embedded-firebase-analytics.yml b/rules/mastg-android-sensitive-data-to-embedded-firebase-analytics.yml new file mode 100644 index 00000000000..82acc3304b0 --- /dev/null +++ b/rules/mastg-android-sensitive-data-to-embedded-firebase-analytics.yml @@ -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 \ No newline at end of file diff --git a/techniques/android/MASTG-TECH-0108.md b/techniques/android/MASTG-TECH-0108.md index f60ef3a541f..c881b3515ee 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 35d24c5e45b..88f88a42a6d 100644 --- a/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0206.md +++ b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0206.md @@ -29,6 +29,6 @@ The output should contain a network traffic sensitive data log that includes the ## Evaluation -The test case fails if you can find the sensitive data you entered in the app that is not stated in the App Store Privacy declarations. +The test case fails if you can find the sensitive data you entered into the app that is not stated in the App Store Privacy declarations. -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-0297 for more details. diff --git a/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0297.md b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0297.md new file mode 100644 index 00000000000..3fd1550d03a --- /dev/null +++ b/tests-beta/android/MASVS-PRIVACY/MASTG-TEST-0297.md @@ -0,0 +1,36 @@ +--- +platform: android +title: App Exposing Sensitive Data to Embedded Libraries +id: MASTG-TEST-0297 +type: [static, dynamic] +weakness: MASWE-xxxA // TODO see https://github.com/OWASP/maswe/pull/11 +prerequisites: + - identify-sensitive-data +profiles: [P] +--- + +## Overview + +This test case verifies the identification of potentially sensitive data that may have been 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. Still, if the SDK is not used correctly, it could inadvertently send sensitive information (like PIIs - Personal Identifiable Information, or secrets) to that third-party service. + +## Steps + +To investigate this, you have two options: + +### Method 1 + +1. Use @MASTG-TOOL-0001 to hook all network functions (and try to detect PII or secrets in their calls). Use the backtraces to find out which component is sending what PII or secrets. This should also include the corresponding network domains. It should provide excellent coverage while staying sufficiently generic. + +### Method 2 + +1. Identify the package name of the embedded library you wish to run the test against, or the list of package names of embedded libraries, by generating an SBOM. + - (optional) To generate an SBOM, you can use tools like @MASTG-TOOL-0130 or @MASTG-TOOL-0134 with @MASTG-TECH-0130 or @MASTG-TECH-0131 to identify all embedded/3rd-party libraries used by the app. You may consult @MASTG-TECH-0130. Shortlist the embedded/3rd-party libraries' APIs that have network functionality and that should not handle sensitive information. You can research those libraries online or their codebase to see if they have network functionality. Look for permissions like `INTERNET` or `ACCESS_NETWORK_STATE` in their manifest files, or check their documentation for network-related features. +2. Identify common APIs of the library/these libraries that are used to send data to their servers. Use @MASTG-TECH-0110, potentially with @MASTG-TOOL-0108, to identify the entry points where sensitive data may be passed to the APIs. You can research those libraries online or their codebase for entry points. The entry points would be "package name" plus "method path and name". For example, if the library is `com.example.analytics` and it has a method `trackEvent(String eventName, Map properties)`, then the entry point would be `com.example.analytics.trackEvent`. + +## 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 passed to embedded/3rd-party libraries that have network functionality, or if network requests to third-party servers contain sensitive information. diff --git a/tests/android/MASVS-STORAGE/MASTG-TEST-0004.md b/tests/android/MASVS-STORAGE/MASTG-TEST-0004.md index 5ef713be316..fee6db25126 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-0297] +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.