deardaniel/secdata-raw huggingface dataset:
OWASP Mobile Application Security Testing Guide: output

[*] open called to open a file from external storage at: /storage/emulated/0/Android/data/org.owasp.mastestapp/files/secret.txt

Backtrace:
libcore.io.Linux.open(Native Method)
libcore.io.ForwardingOs.open(ForwardingOs.java:563)
libcore.io.BlockGuardOs.open(BlockGuardOs.java:274)
libcore.io.ForwardingOs.open(ForwardingOs.java:563)
android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8063)
libcore.io.IoBridge.open(IoBridge.java:560)
java.io.FileOutputStream.<init>(FileOutputStream.java:236)
java.io.FileOutputStream.<init>(FileOutputStream.java:186)
org.owasp.mastestapp.MastgTest.mastgTestApi(MastgTest.kt:26)
org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:16)
org.owasp.mastestapp.MainActivityKt.MainScreen$lambda$9$lambda$8(MainActivity.kt:53)
org.owasp.mastestapp.MainActivityKt.$r8$lambda$PhzGLzmkS_ibruOfiTT32AhzWl4(Unknown Source:0)
org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
java.lang.Thread.run(Thread.java:1012)

[*] ContentResolver.insert called with ContentValues:
        _display_name: secretFile59.txt
        mime_type: text/plain
        relative_path: Download

[*] ContentResolver.insert returned URI: content://media/external/downloads/[PII_REDACTED]

Backtrace:
android.content.ContentResolver.insert(Native Method)
org.owasp.mastestapp.MastgTest.mastgTestMediaStore(MastgTest.kt:44)
org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:17)
org.owasp.mastestapp.MainActivityKt.MainScreen$lambda$9$lambda$8(MainActivity.kt:53)
org.owasp.mastestapp.MainActivityKt.$r8$lambda$PhzGLzmkS_ibruOfiTT32AhzWl4(Unknown Source:0)
org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
java.lang.Thread.run(Thread.java:1012)
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0002

---
platform: android
title: External Storage APIs Tracing with Frida
id: MASTG-DEMO-0002
code: [kotlin]
test: MASTG-TEST-0201
---

## Sample

The snippet below shows sample code that creates two files in external storage using the `getExternalFilesDir` method and the `MediaStore` API.

{{ MastgTest.kt }}

## 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. Click the **Start** button
5. Stop the script by pressing `Ctrl+C`

The `run.sh` script injects a @MASTG-TOOL-0001 script named `script.js`. This script hooks and logs calls to the native `open` function and to `android.content.ContentResolver.insert`. It logs the paths of files written to external storage, the caller's stack trace, and additional details such as the `ContentValues` provided.

!!! note
    When apps write files using the `ContentResolver.insert()` method, the files are managed by Android's MediaStore and are identified by `content://` URIs, not direct file system paths. This design abstracts the actual file locations, making them inaccessible through standard file system operations like the `open` function in libc. Consequently, when using Frida to hook into file operations, intercepting calls to `open` won't reveal these files.

{{ run.sh # script.js }}

## Observation

In the output you can observe the file paths, the relevant stack traces, and other details that help identify which APIs were used to write to external storage and their respective callers.

{{ output.txt }}

Two files are written to external storage:

- `/storage/emulated/0/Android/data/org.owasp.mastestapp/files/secret.txt`:
    - Written via `java.io.FileOutputStream`
    - Location: `org.owasp.mastestapp.MastgTest.mastgTestApi(MastgTest.kt:26)`.
- `secretFile55.txt`:
    - Written via `android.content.ContentResolver.insert`
    - Location: `org.owasp.mastestapp.MastgTest.mastgTestMediaStore(MastgTest.kt:44)`.
    - Found as URI: `content://media/external/downloads/[PII_REDACTED]`.

The `ContentResolver.insert` call used the following `ContentValues`:

- `_display_name: secretFile55.txt`
- `mime_type: text/plain`
- `relative_path: Download`

Using this information we can infer the path of the file written to external storage: `/storage/emulated/0/Download/secretFile55.txt`.

## Evaluation

This test fails because the files are not encrypted and contain sensitive data (such as a password and an API key). This can be further confirmed by reverse-engineering the app to inspect its code and retrieving the files from the device.
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0001

---
platform: android
title: File System Snapshots from External Storage
id: MASTG-DEMO-0001
code: [kotlin]
test: MASTG-TEST-0200
---

## Sample

The snippet below shows sample code that creates two files in the external storage using the `getExternalFilesDir` method and the `MediaStore` API.

{{ MastgTest.kt }}

## Steps

1. Install an app on your device.
2. Execute `run_before.sh` which runs @MASTG-TOOL-0004.
3. Open an app and exercise it to trigger file creations.
4. Execute `run_after.sh`.
5. Close the app once you finish testing.

{{ run_before.sh # run_after.sh }}

## Observation

There is a list of all created files inside `output.txt`.

{{ output.txt }}

Their content is inside the `./new_files/` directory and contains:

A password:

{{ new_files/secret.txt }}

And an API key:

{{ new_files/secretFile75.txt }}

## Evaluation

This test fails because the files are not encrypted and contain sensitive data (a password and an API key). You can further confirm this by reverse engineering the app and inspecting the code.
OWASP Mobile Application Security Testing Guide: output

                   
                   
┌─────────────────┐
│ 4 Code Findings │
└─────────────────┘
                           
    MastgTest_reversed.java
    ❯❱ rules.mastg-android-keyboard-cache-input-types
          [MASVS-STORAGE] Set input type detected ($this$showPopup_u24lambda_u241) with 129
                                                                                           
           35┆ $this$showPopup_u24lambda_u241.setInputType(129);
            ⋮┆----------------------------------------
    ❯❱ rules.mastg-android-keyboard-cache-input-types
          [MASVS-STORAGE] Set input type detected ($this$showPopup_u24lambda_u242) with 1
                                                                                         
           38┆ $this$showPopup_u24lambda_u242.setInputType(1);
            ⋮┆----------------------------------------
    ❯❱ rules.mastg-android-keyboard-cache-input-types
          [MASVS-STORAGE] Set input type detected (input3) with 18
                                                                  
           41┆ input3.setInputType(18);
            ⋮┆----------------------------------------
    ❯❱ rules.mastg-android-keyboard-cache-input-types
          [MASVS-STORAGE] Set input type detected (input3) with 2
                                                                 
           42┆ input3.setInputType(2);
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0064

---
platform: android
title: Uses of Caching UI Elements with semgrep
id: MASTG-DEMO-0064
code: [kotlin]
test: MASTG-TEST-0258
---

## Sample

The code sample defines a method that creates a popup dialog for user input where 3 text input fields (`EditText`) are instantiated. For each `EditText`, the `inputType` property is set to define the type of input expected:

- **password**: should not be cached due to `TYPE_TEXT_VARIATION_PASSWORD`
- **passphrase**: should be cached due to `TYPE_CLASS_TEXT`
- **PIN**: should be cached due to `TYPE_CLASS_NUMBER`, despite initially being set to `TYPE_NUMBER_VARIATION_PASSWORD`

A dialog is also created using `AlertDialog.Builder`, and it includes "Sign Up" and "Cancel" buttons.

{{ MastgTest.kt # MastgTest_reversed.java }}

## Steps

Let's run @MASTG-TOOL-0110 rule against the sample code. The rule uses a pattern that captures every call to `setInputType` along with its argument.

{{ ../../../../rules/mastg-android-keyboard-cache-input-types.yml }}

{{ run.sh }}

## Observation

The rule has detected several instances. For each one, the output shows:

- The line number.
- The object name in the reversed code (e.g. `$this$showPopup_u24lambda_u241` or `input3`).
- The `setInputType` method itself.
- The argument including the input type value (e.g., `129`).

{{ output.txt }}

## Evaluation

The test fails because the app doesn't use non-caching input types for some sensitive fields. Only the first input field (password) is configured correctly. The other two fields (passphrase and PIN) are set to caching input types.

> See the Android [InputType documentation](https://developer.android.com/reference/android/text/InputType) for details about what each numeric value represents.

**(PASS)** Object `showPopup_u24lambda_u241` is set as `129`:

```python
129 & 0x0000000F  #   1 (TYPE_CLASS_TEXT)
129 & 0x00000FF0  # 128 (TYPE_TEXT_VARIATION_PASSWORD)
```

This is correct because it prevents the password from being cached.

**(FAIL)** Object `showPopup_u24lambda_u242` is set as `1` (`TYPE_CLASS_TEXT`).

```python
1 & 0x0000000F  #   1 (TYPE_CLASS_TEXT)
```

This is incorrect because it allows the passphrase to be cached. The correct value should be `129` (`TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD`).

**(FAIL)** Object `input3` is first set to `18`:

```python
18 & 0x0000000F  #   2 (TYPE_CLASS_NUMBER)
18 & 0x00000FF0  #  16 (TYPE_NUMBER_VARIATION_PASSWORD)
```

This would be correct, however, in the reversed code, there's a second `setInputType` call that sets the input type to `2` (`TYPE_CLASS_NUMBER`), which is a caching input type:

```python
2 & 0x0000000F  #   2 (TYPE_CLASS_NUMBER)
```

This is incorrect because it allows the PIN to be cached. The correct value should be `18` (`TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_PASSWORD`).
OWASP Mobile Application Security Testing Guide: output

                  
                  
┌────────────────┐
│ 1 Code Finding │
└────────────────┘
                           
    MastgTest_reversed.java
    ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-external-api-public
          [MASVS-STORAGE] Make sure to encrypt files at these locations if necessary
                                                                                    
           27┆ File externalStorageDir = Environment.getExternalStorageDirectory();
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0003

---
platform: android
title: App Writing to External Storage without Scoped Storage Restrictions
id: MASTG-DEMO-0003
code: [kotlin, xml]
test: MASTG-TEST-0202
---

## Sample

The snippet below shows sample code that creates a file in external storage without using scoped storage APIs. The `getExternalStorageDirectory` API returns a path to the root of the shared external storage (e.g. `/storage/emulated/0`).

This requires special app access called ["All files access"](https://developer.android.com/preview/privacy/storage#all-files-access), so the `MANAGE_EXTERNAL_STORAGE` permission must be declared in the manifest file.

{{ MastgTest.kt # MastgTest_reversed.java # AndroidManifest.xml # AndroidManifest_reversed.xml }}

## Steps

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

{{ ../../../../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-apis.yml }}

And another one against the sample manifest file.

{{ ../../../../rules/mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest.yml }}

{{ run.sh }}

## Observation

The rule has identified one location in the code file where an API, `getExternalStorageDirectory`, is used to write to external storage as well as the location in the manifest file where the `MANAGE_EXTERNAL_STORAGE` permission is declared.

{{ output.txt # output2.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 data, specifically a password.
OWASP Mobile Application Security Testing Guide: output2

                  
                  
┌────────────────┐
│ 1 Code Finding │
└────────────────┘
                                
    AndroidManifest_reversed.xml
    ❯❱ rules.mastg-android-data-unencrypted-shared-storage-no-user-interaction-manifest
          [MASVS-STORAGE] Make sure to encrypt files in external storage if necessary
                                                                                     
            2┆ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0060

---
platform: android
title: App Writing Sensitive Data to Sandbox using EncryptedSharedPreferences
id: MASTG-DEMO-0060
code: [kotlin]
test: MASTG-TEST-0287
kind: pass
---

## Sample

The code snippet below shows sample code which stores sensitive data using `String` and `StringSet` from `EncryptedSharedPreferences`.

!!! Warning

    The **Jetpack security crypto library**, including the `EncryptedFile` and  `EncryptedSharedPreferences` classes, has been [deprecated](https://developer.android.com/privacy-and-security/cryptography#jetpack_security_crypto_library). However, since an official replacement has not yet been released, we recommend using these classes until one is available.

{{ MastgTest.kt # build.gradle.kts.libs }}

## Steps

1. Install the app on a device (@MASTG-TECH-0005)
2. Make sure you have @MASTG-TOOL-0145 installed on your machine and the frida-server running on the device
3. Run `run.sh` to spawn the app with Frida
4. Click the **Start** button
5. Stop the script by pressing `Ctrl+C` and/or `q` to quit the Frida CLI

{{ hooks.json # run.sh }}

## Observation

The output shows all instances of strings written using `EncryptedSharedPreferences` via `SharedPreferences` that were found at runtime. A backtrace is also provided to help identify the location in the code.

{{ output.json }}

## Evaluation

This test **passes** because sensitive data is stored using `EncryptedSharedPreferences`, which encrypts both keys and values at rest. Even if an attacker gains access to the app's sandbox, the data remains encrypted.

For example, to confirm this, run the following command:

```sh
adb shell cat /data/data/org.owasp.mastestapp/shared_prefs/MasSharedPref_Sensitive_Data.xml
```

Which returns:

{{ MasSharedPref_Sensitive_Data.xml }}

The actual values are not visible in plain text, confirming that encryption is applied.
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0035

---
platform: android
title: Data Exclusion using backup_rules.xml with adb backup
id: MASTG-DEMO-0035
code: [kotlin]
test: MASTG-TEST-0216
---

## Sample

This demo uses the sample from @MASTG-DEMO-0020.

{{ ../MASTG-DEMO-0020/MastgTest.kt # ../MASTG-DEMO-0020/AndroidManifest.xml # ../MASTG-DEMO-0020/backup_rules.xml }}

## Steps

1. Install the target app on your device.
2. Open the app and exercise it to trigger file creations.
3. Execute `run.sh`.

{{ run.sh # ../../../../utils/mastg-android-backup-adb.sh }}

For simplicity, in `run.sh` we restrict the files to the `filesDir` directory in the backup structure (`apps/org.owasp.mastestapp/f`).

## Observation

The output contains:

- `output.txt`: the list of files from the backup.
- `apps/org.owasp.mastestapp/f/`: the directory containing a copy of the backup files.

{{ output.txt }}

## Evaluation

The test fails because `secret.txt` is part of the backup and it contains sensitive data.

{{ apps/org.owasp.mastestapp/f/secret.txt }}

Note that `backup_excluded_secret.txt` file is not part of the backup, which is expected as it was marked as `exclude` in the `backup_rules.xml` file.
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0068

---
platform: android
title: Sensitive Data in Unencrypted SQLite
id: MASTG-DEMO-0068
code: [kotlin]
test: MASTG-TEST-0304
status: placeholder
note: This placeholder reserves the ID for a potential alternative or expanded demo related to unencrypted SQLite storage, linked to the MASTG-TEST-0304 test case.
---
OWASP Mobile Application Security Testing Guide: output

                   
                   
┌─────────────────┐
│ 4 Code Findings │
└─────────────────┘
                                
    AndroidManifest_reversed.xml
    ❯❱ rules.detect-dangerous-android-permissions
          Dangerous Android permission found:
                                             
            3┆ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
            ⋮┆----------------------------------------
            4┆ <uses-permission android:name="android.permission.READ_CONTACTS"/>
            ⋮┆----------------------------------------
            5┆ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
            ⋮┆----------------------------------------
            6┆ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0033

---
platform: android
title: Dangerous Permissions in the AndroidManifest with semgrep
id: MASTG-DEMO-0033
code: [kotlin]
test: MASTG-TEST-0254
---

## Sample

The following is a sample AndroidManifest file that declares 4 dangerous permissions.

{{ AndroidManifest.xml # AndroidManifest_reversed.xml }}

## Steps

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

{{ ../../../../rules/mastg-android-dangerous-app-permissions.yaml }}

{{ run.sh }}

## Observation

The rule has identified four instances in the AndroidManifest file where the app declares dangerous permissions.

{{ output.txt }}

## Evaluation

The test fails because the app declares the following dangerous permissions:

- `WRITE_EXTERNAL_STORAGE`
- `READ_CONTACTS`
- `READ_EXTERNAL_STORAGE`
- `ACCESS_FINE_LOCATION`
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0081

---
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-0145 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.json # 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).
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0009

---
platform: android
title: Detecting Undeclared PII in Network Traffic
id: MASTG-DEMO-0009
code: [kotlin]
test: MASTG-TEST-0206
---

## Sample

The snippet below shows sample code that sends sensitive data over the network using the `HttpURLConnection` class. The data is sent to `https://httpbin.org/post` which is a dummy endpoint that returns the data it receives.

!!! note
    This demo app is not published on Google Play. However, imagine it represents a production application in which none of the sensitive data transmitted here is declared in the app's privacy policy or in its store disclosure (Data Safety Section).

{{ MastgTest.kt # MastgTest_reversed.java }}

## Steps

Start the device, in this case, the Android emulator:

```bash
emulator -avd Pixel_3a_API_33_arm64-v8a -writable-system
```

Run @MASTG-TOOL-0097 with the custom script for logging sensitive data and dump the relevant traffic to a file.

Note that the script is preconfigured with data that's already considered sensitive for this application. When running this test in a real-world scenario, you should determine what is considered [sensitive data](../../../../Document/0x04b-Mobile-App-Security-Testing.md#identifying-sensitive-data "Sensitive Data") based on the app's privacy policy and relevant privacy regulations. One recommended way to do this is by checking the app's privacy policy and the App Store Privacy declarations.

{{ mitm_sensitive_logger.py }}

{{ run.sh }}

Launch the app from Android Studio and click the button which will send the sensitive data over the network. The script will capture the network traffic and log the sensitive data.

## Observation

The script has identified several instances of sensitive data in the network traffic.

- The first instance is a POST request to `https://httpbin.org/post` which contains the sensitive data values in the request body.
- The second instance is a response from `https://httpbin.org/post` which contains the sensitive data values in the response body.

{{ sensitive_data.log }}

## Evaluation

After reviewing the captured network traffic, we can conclude that the test fails because the sensitive data is sent over the network.

This is a dummy example, but in a real-world scenario, you should identify which reported instances are relevant to privacy and require remediation because they are not included in the app's privacy policy or the App Store privacy declaration.

Note that both the request and the response are encrypted using TLS, so they can be considered secure. However, this might represent a privacy issue depending on the relevant privacy regulations and the app's privacy policy. You should now check the privacy policy and the App Store Privacy declarations to see if the app is allowed to send this data to a third-party.
OWASP Mobile Application Security Testing Guide: output

                   
                   
┌─────────────────┐
│ 3 Code Findings │
└─────────────────┘
                           
    MastgTest_reversed.java
    ❯❱ rules.mastg-android-hardcoded-crypto-keys-usage
          [MASVS-CRYPTO-1] Hardcoded cryptographic keys found in use.
                                                                     
           24┆ byte[] keyBytes = {108, 97, 107, 100, 115, 108, 106, 107, 97, 108, 107, 106, 108, 107, 108,
               115};                                                                                      
           25┆ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
           26┆ SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
            ⋮┆----------------------------------------
           26┆ SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
            ⋮┆----------------------------------------
           30┆ SecretKeySpec badSecretKeySpec = new SecretKeySpec(bytes, "AES");