deardaniel/secdata-raw huggingface dataset:
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0028

---
platform: android
title: Uses of KeyguardManager.isDeviceSecure and BiometricManager.canAuthenticate with semgrep
id: MASTG-DEMO-0028
code: [kotlin]
test: MASTG-TEST-0247
---

## Sample

This sample checks if the device has a secure lock screen via `KeyguardManager.isDeviceSecure` and if the device supports strong biometric authentication using `BiometricManager.canAuthenticate`.

{{ MastgTest.kt # MastgTest_reversed.java }}

## Steps

Let's run @MASTG-TOOL-0110 rules against the sample code.

{{ ../../../../rules/mastg-android-device-passcode-present.yml }}

{{ run.sh }}

## Observation

The output shows all usages of APIs related to secure screen lock detection.

{{ output.txt }}

## Evaluation

The test passes because the output shows references to APIs that check for secure screen lock presence, specifically:

- `KeyguardManager.isDeviceSecure` in line 33
- `BiometricManager.canAuthenticate` in line 39
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0107

---
platform: android
title: Detecting Frida hooks and terminating the application on response
id: MASTG-DEMO-0107
code: [kotlin]
test: MASTG-TEST-0341
kind: pass
---

## Sample

This sample encrypts and decrypts a sensitive API key using AES/GCM via the Android KeyStore. Unlike the unprotected variant in @MASTG-DEMO-0106, this version includes a runtime hook detection mechanism that reads `/proc/self/maps` to check for the presence of Frida-related libraries (e.g., `frida-agent`, `frida-gadget`). If detected, the app terminates the process immediately via `Process.killProcess()` before any cryptographic operations are performed.

!!! note
    This is a series of correlated tests.

    - @MASTG-DEMO-0106 is a failed test (failed defence/successful attack) against a data exfiltration attack.
    - This test is a successful test (successful defense/failed attack) against the attack of @MASTG-DEMO-0106.
    - @MASTG-DEMO-0108 is a failed test (failed defence/successful attack) against the defenses of @MASTG-DEMO-0107 by using a more "complex" attack.

{{ MastgTest.kt }}

## 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. Observe that the app terminates before the hooks can capture any data

{{ hooks.json # run.sh }}

## Observation

The output contains no instances of `Cipher` method calls found at runtime. The app terminated before any hooks could capture data.

{{ output.json }}

## Evaluation

The test passes because the hooking attempt fails due to the app's defensive response. The app detects the Frida agent by scanning `/proc/self/maps` for entries containing "frida" or "gadget" and terminates the process via `Process.killProcess()`. The process terminates before `Cipher.doFinal()` hooks execute, so no sensitive data is extracted.

!!! note
    Even if the test case passes, it might still be possible to bypass the app's defensive response. For example, an attacker could hook the `detectHooking()` method itself or lower level APIs such as the file reading APIs to hide Frida from the process memory map. @MASTG-DEMO-0108 demonstrates such a bypass. @MASTG-KNOW-0030 and @MASTG-KNOW-0032 describe such challenges.
OWASP Mobile Application Security Testing Guide: output

                   
                   
┌─────────────────┐
│ 5 Code Findings │
└─────────────────┘
                           
    MastgTest_reversed.java
     ❱ rules.mastg-android-root-detection-file-checks
          [MASVS-RESILIENCE-1] The app checks for file existence, which may be part of root detection
          implementation.                                                                            
                                                                                                     
           63┆ boolean exists = new File(path).exists();
   
     ❱ rules.mastg-android-root-detection-runtime-exec
          [MASVS-RESILIENCE-1] The app uses Runtime.exec(), which may be attempting to execute su or other
          commands for root detection.                                                                    
                                                                                                          
           83┆ Process process = Runtime.getRuntime().exec(new String[]{"which", "su"});
   
     ❱ rules.mastg-android-root-detection-package-check
          [MASVS-RESILIENCE-1] The app checks for installed packages, which may be looking for root management
          apps.                                                                                               
                                                                                                              
          133┆ this.context.getPackageManager().getPackageInfo(packageName, 0);
   
     ❱ rules.mastg-android-root-detection-test-keys
          [MASVS-RESILIENCE-1] The app checks Build.TAGS for test-keys, indicating custom ROM or root
          detection.                                                                                 
                                                                                                     
          151┆ if (buildTags != null && StringsKt.contains$default((CharSequence) buildTags,
               (CharSequence) "test-keys", false, 2, (Object) null)) {                      
   
     ❱ rules.mastg-android-root-detection-system-properties
          [MASVS-RESILIENCE-1] The app reads system properties via getprop, which may be checking for root
          indicators.                                                                                     
                                                                                                          
          180┆ Process process = Runtime.getRuntime().exec(new String[]{"getprop", key});
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0087

---
platform: android
title: Uses of Root Detection Techniques with Semgrep
id: MASTG-DEMO-0087
code: [kotlin, xml]
test: MASTG-TEST-0324
tools: [MASTG-TOOL-0110]
kind: pass
---

## Sample

This sample demonstrates common root detection techniques used in Android applications, including:

- Checking for the `su` binary in common locations
- Checking for the `su` binary using the `which` command
- Detecting root management packages using `PackageManager`
- Identifying `test-keys` builds indicating custom ROMs
- Reading system properties that may indicate root or debugging

To ensure that the requests using `PackageManager.getPackageInfo` work as expected, the app includes the relevant `<queries>` element in the `AndroidManifest.xml`.

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

## Steps

Let's run @MASTG-TOOL-0110 with the following rule:

{{ ../../../../rules/mastg-android-root-detection.yaml }}

{{ run.sh }}

## Observation

The output shows all locations where root detection checks are implemented in the code.

{{ output.txt }}

## Evaluation

The test passes because the output shows multiple root detection implementations:

- Line 63: File existence checks for `su` binaries and root-related files
- Line 83: `which su` command execution
- Line 133: `PackageManager` checks for root management apps
- Line 151: `Build.TAGS` check for `test-keys` indicating custom ROM
- Line 180: `Runtime.exec()` and `getprop` calls to read system properties
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0088

---
platform: android
title: Runtime Detection of Root Detection Mechanisms
id: MASTG-DEMO-0088
code: [kotlin]
test: MASTG-TEST-0325
tools: [MASTG-TOOL-0145]
---

## Sample

This demo shows how to detect root detection mechanisms at runtime using Frooky. The sample app from @MASTG-DEMO-0087 implements multiple root detection checks.

{{ ../MASTG-DEMO-0087/MastgTest.kt }}

## Steps

1. Ensure the target app is installed on the device and frida-server is running.
2. Run @MASTG-TOOL-0145 with the hooks configuration to monitor root detection methods.

{{ run.sh }}

The hooks configuration monitors common root detection methods:

{{ hooks.json }}

## Observation

The output shows all root detection method invocations captured during app execution.

{{ output.json }}

## Evaluation

The test passes because the output confirms the app implements root detection checks that were monitored at runtime:

- **`java.io.File.<init>` calls for `su` path checks:**
    - From `MastgTest.checkForSuBinary()` at line 61.
    - The app checks for 10 `su` binary locations such as `/system/app/Superuser.apk`, `/sbin/su`, `/system/bin/su`, `/system/xbin/su`, etc.
    - Additional constructor calls from libraries like `androidx.profileinstaller.ProfileInstaller` may appear in the trace but are not related to root detection.

- **`Runtime.exec` calls for `which su` command:**
    - From `MastgTest.checkForWhichSu()` at line 81.
    - The app executes the `which su` command to detect if the `su` binary is available in the system PATH.

- **`PackageManager.getPackageInfo` calls for root packages:**
    - From `MastgTest.checkForRootPackages` at line 133.
    - The app checks for 12 root management packages including `com.topjohnwu.magisk`, `eu.chainfire.supersu`, etc. In the captured output, the relevant `getPackageInfo` calls throw `NameNotFoundException` as expected since none of these packages are installed.
    - Additional `getPackageInfo` calls from system or library components may appear in the trace but are unrelated to root detection.

- **`Runtime.exec` calls for system property checks:**
    - From `MastgTest.getSystemProperty` at line 181, called by `checkForDangerousProps`.
    - The app executes `getprop ro.debuggable` and `getprop ro.secure` commands to read system properties.
OWASP Mobile Application Security Testing Guide: output

[+] BufferedReader.readLine() hooked: filtering Frida-related entries from /proc/self/maps
[+] Cipher.doFinal() hooked: extracting sensitive data

[*] Hiding line from /proc/self/maps: 6d69a0b000-6d6a351000 r--p 00000000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d6a352000-6d6b092000 r-xp 00946000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d6b092000-6d6b163000 r--p 01685000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d6b164000-6d6b17f000 rw-p 01756000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d69a0b000-6d6a351000 r--p 00000000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d6a352000-6d6b092000 r-xp 00946000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d6b092000-6d6b163000 r--p 01685000 00:01 188                            /memfd:frida-agent-64.so (deleted)
[*] Hiding line from /proc/self/maps: 6d6b164000-6d6b17f000 rw-p 01756000 00:01 188                            /memfd:frida-agent-64.so (deleted)


[*] Cipher.doFinal(byte[]) called
    Algorithm: AES/GCM/NoPadding
    Mode: ENCRYPT_MODE
    Input (plaintext): sk-OWASP-MAS-SuperSecretKey[PII_REDACTED]
    Output (ciphertext hex): e9ff1fd068d108fad6e3e64aca3ce460c169d956123a119ab596887d7f62d14245a24eeb93da5cb8395bbab4f8bc637d0852221fc96e

Backtrace:
javax.crypto.Cipher.doFinal(Native Method)
org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:79)
org.owasp.mastestapp.MainActivityKt.MainScreen$lambda$12$lambda$11(MainActivity.kt:101)
org.owasp.mastestapp.MainActivityKt.$r8$lambda$Pm6AsbKBmypP53K-UABM21E_Xxk(Unknown Source:0)
org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda3.run(D8$$SyntheticClass:0)
java.lang.Thread.run(Thread.java:1119)


[*] Cipher.doFinal(byte[]) called
    Algorithm: AES/GCM/NoPadding
    Mode: DECRYPT_MODE
    Input (ciphertext hex): e9ff1fd068d108fad6e3e64aca3ce460c169d956123a119ab596887d7f62d14245a24eeb93da5cb8395bbab4f8bc637d0852221fc96e
    Output (plaintext): sk-OWASP-MAS-SuperSecretKey[PII_REDACTED]

Backtrace:
javax.crypto.Cipher.doFinal(Native Method)
org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:89)
org.owasp.mastestapp.MainActivityKt.MainScreen$lambda$12$lambda$11(MainActivity.kt:101)
org.owasp.mastestapp.MainActivityKt.$r8$lambda$Pm6AsbKBmypP53K-UABM21E_Xxk(Unknown Source:0)
org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda3.run(D8$$SyntheticClass:0)
java.lang.Thread.run(Thread.java:1119)
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0108

---
platform: android
title: Bypassing Frida Detection in /proc/self/maps to Extract Sensitive Data
id: MASTG-DEMO-0108
code: [kotlin]
test: MASTG-TEST-0341
kind: fail
---

## Sample

This sample uses the same code as @MASTG-DEMO-0107, which encrypts and decrypts a sensitive API key using AES/GCM via the Android KeyStore. The code includes a runtime hook detection mechanism that scans `/proc/self/maps` for Frida-related libraries and terminates the process via `Process.killProcess()` if any are found. This demo demonstrates bypassing the detection by hooking `BufferedReader.readLine()` to hide Frida entries from `/proc/self/maps`, causing `detectHooking()` to return `false` so the termination path is never reached.

See @MASTG-KNOW-0030 and @MASTG-KNOW-0032 for more context on bypassing runtime detection mechanisms.

!!! note
    This is a series of correlated tests.

    - @MASTG-DEMO-0106 is a failed test (failed defence/successful attack) against a data exfiltration attack.
    - @MASTG-DEMO-0107 is a successful test (successful defense/failed attack) against the attack of @MASTG-DEMO-0106.
    - This test is a failed test (failed defence/successful attack) against the defenses of @MASTG-DEMO-0107 by using a more "complex" attack.

{{ ../MASTG-DEMO-0107/MastgTest.kt }}

## Steps

1. Install the app on a device (@MASTG-TECH-0005)
2. Run `run.sh` to spawn the app with the bypass script
3. Click the **Start** button
4. Stop the script by pressing `Ctrl+C` and/or `q` to quit the Frida CLI

{{ bypass.js # run.sh }}

## Observation

The output contains eight `frida-agent-64.so` memory segments filtered from `/proc/self/maps` across two scans. Two `Cipher.doFinal()` calls are captured: one in `ENCRYPT_MODE` with the plaintext input `sk-OWASP-MAS-SuperSecretKey[PII_REDACTED]`, and another in `DECRYPT_MODE` with the same plaintext as output.

{{ output.txt }}

## Evaluation

The test fails because the `BufferedReader.readLine()` hook successfully concealed all Frida memory segments from `/proc/self/maps`, causing `detectHooking()` to return `false`. With detection bypassed, the app proceeded with its cryptographic operations, which were intercepted by the `Cipher.doFinal()` hooks to extract the sensitive API key `sk-OWASP-MAS-SuperSecretKey[PII_REDACTED]` in plaintext.
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0037

---
platform: android
title: App Leaking Information about Unclosed SQL Cursor via StrictMode
id: MASTG-DEMO-0037
code: [kotlin]
test: MASTG-TEST-0263
---

## Sample

The snippet below shows sample code that enables a `StrictMode` policy to detect leaked (i.e., unclosed) SQLite objects. When such an object is detected, a log message is emitted to the system log.

The snippet then opens an SQL Cursor which remains unclosed, to trigger the policy.

{{ MastgTest.kt }}

## Steps

1. Install the app on your device.
2. Open the app and let it execute.
3. Execute `run.sh` which uses @MASTG-TECH-0009 to show the system logs created by `StrictMode`.

{{ run.sh }}

## Observation

The system log outputs all detected `StrictMode` policy violations.

{{ output.txt }}

## Evaluation

The test fails because `StrictMode` is enabled, as we can see from the system log output which shows that there is a location (`MastgTest.kt:35`) where an SQL cursor is not closed properly.

**Note:** The reported cursor not being closed is a different issue outside the scope of this demo.
OWASP Mobile Application Security Testing Guide: output

                  
                  
┌────────────────┐
│ 1 Code Finding │
└────────────────┘
                           
    MastgTest_reversed.java
    ❯❱ rules.mastg-android-strictmode
          [MASVS-RESILIENCE] Detected usage of StrictMode
                                                         
           29┆ StrictMode.setVmPolicy(new                                                        
               StrictMode.VmPolicy.Builder().detectLeakedClosableObjects().penaltyLog().build());
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0039

---
platform: android
title: Detecting StrictMode PenaltyLog Usage with Semgrep
id: MASTG-DEMO-0039
code: [kotlin]
test: MASTG-TEST-0265
---

## Sample

This sample demonstrates the static detection of `StrictMode` in the app using Semgrep. The app enables a `StrictMode` policy to detect leaked SQLite objects and intentionally leaves a cursor unclosed to trigger the policy.

{{ ../MASTG-DEMO-0037/MastgTest.kt # MastgTest_reversed.java }}

## Steps

Let's run @MASTG-TOOL-0110 rules against the sample code.

{{ ../../../../rules/mastg-android-strictmode.yml }}

{{ run.sh }}

## Observation

The output shows all usages of APIs related to `StrictMode.setVmPolicy`.

{{ output.txt }}

## Evaluation

The test fails because the output shows usages of `StrictMode.setVmPolicy`.
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0106

---
platform: android
title: Extracting Sensitive Data from Cipher.doFinal via Frida Hooking
id: MASTG-DEMO-0106
code: [kotlin]
test: MASTG-TEST-0341
kind: fail
---

## Sample

This sample encrypts and decrypts a sensitive API key using AES/GCM via the Android KeyStore. The app does not implement any runtime hook detection mechanisms. On the contrary, @MASTG-DEMO-0107 demonstrates a runtime hook detection mechanism.

!!! note
    This is a series of correlated tests.

    - This test is a failed test (failed defence/successful attack) against a data exfiltration attack.
    - @MASTG-DEMO-0107 is a successful test (successful defense/failed attack) against the attack of @MASTG-DEMO-0106.
    - @MASTG-DEMO-0108 is a failed test (failed defence/successful attack) against the defenses of @MASTG-DEMO-0107 by using a more "complex" attack.

{{ MastgTest.kt }}

## 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 contains all instances of `Cipher.doFinal()` method calls found at runtime. A backtrace is also provided to help identify the location in the code. The first `doFinal` call reveals the sensitive API key in plaintext as the input parameter during encryption and the second call reveals it as the return value during decryption.

{{ output.json }}

## Evaluation

The test fails because the hook executes successfully and the sensitive API key `sk-OWASP-MAS-SuperSecretKey[PII_REDACTED]` is extracted in plaintext from the `Cipher.doFinal()` calls. The app lacks runtime integrity verification, allowing instrumentation tools to intercept cryptographic operations without any defensive response.
OWASP Mobile Application Security Testing Guide: output

                  
                  
┌────────────────┐
│ 1 Code Finding │
└────────────────┘
                               
    network_security_config.xml
    ❯❱ rules.mastg-android-network-insecure-trust-anchors
          The network security config allows certificates imported on the user's behalf thereby allowing
          connections to potentially insecure CAs                                                       
                                                                                                        
            6┆ <certificates src="user" />
OWASP Mobile Application Security Testing Guide: MASTG DEMO 0057

---
platform: android
title: Network Security Configuration Allows User-Added Certificates
id: MASTG-DEMO-0057
code: [xml, kotlin]
test: MASTG-TEST-0286
---

## Sample

This sample Kotlin code fetches the @MASTG-TOOL-0143 server <https://mitm-software.badssl.com/> using `HttpsURLConnection`, which is not normally allowed because the certificate is not trusted by the system. However, due to the Network Security Configuration that permits user-added CA certificates, the connection is allowed to proceed.

{{ MastgTest.kt # AndroidManifest.xml # AndroidManifest_reversed.xml # network_security_config.xml }}

!!! note "Running the app"

    You don't need to run the app on a device or emulator to test this demo because it focuses on the Network Security Configuration. However, if you want to run the app and verify that the connection is allowed, some additional preparation is required:

    1. Obtain the root CA certificate for the server. For this example, obtain it  here: <https://github.com/chromium/badssl.com/blob/master/certs/src/crt/ca-mitm-software.crt>
    2. Copy the certificate file onto the device or emulator. For example, use the command `adb push ca-mitm-software.crt /sdcard/Download/`.
    3. On the device open **Settings > Security > Encryption & credentials > Install from storage** and select your certificate file. Confirm it installs under "User credentials".

## Steps

First of all we obtain the AndroidManifest.xml file (`AndroidManifest_reversed.xml`), which contains the `android:networkSecurityConfig` attribute pointing to the app's Network Security Configuration file (`network_security_config.xml`).

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

{{ ../../../../rules/mastg-android-network-insecure-trust-anchors.yml }}

{{ run.sh }}

## Observation

The rule has identified an element in the Network Security Configuration that allows user-added CA certificates.

{{ output.txt }}

## Evaluation

The test fails due to the `<certificates src="user" />` element in the Network Security Configuration which allows user-added CA certificates.
OWASP Mobile Application Security Testing Guide: output

                  
                  
┌────────────────┐
│ 1 Code Finding │
└────────────────┘
                                  
    MastgTestWebView_reversed.java
    ❯❱ rules.mastg-android-network-onreceivedsslerror
          Improper use of onReceivedSslError handler
                                                    
           27┆ @Override // android.webkit.WebViewClient
           28┆ public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
           29┆     Intrinsics.checkNotNullParameter(view, "view");
           30┆     Intrinsics.checkNotNullParameter(handler, "handler");
           31┆     Intrinsics.checkNotNullParameter(error, "error");
           32┆     String message = this.this$0.getSslErrorMessage(error);
           33┆     Log.e("MastgTestWebView", "SSL errors onReceivedSslError: " + message);
           34┆     Log.e("MastgTestWebView", error.toString());
           35┆     handler.proceed();
           36┆ }