Skip to content

MASTG-DEMO-0039: Detecting StrictMode PenaltyLog Usage with Semgrep

Download MASTG-DEMO-0039 APK Open MASTG-DEMO-0039 Folder Build MASTG-DEMO-0039 APK

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package org.owasp.mastestapp

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.os.StrictMode


class MastgTest (private val context: Context){

    fun mastgTest(): String {
        enableStrictMode()
        triggerSqliteCursorLeak()

        System.gc() // Force garbage collection to trigger leak detection

        return "SUCCESS!!\n\nSQL Cursor leaked."
    }

    private fun enableStrictMode() {
        StrictMode.setVmPolicy(
            StrictMode.VmPolicy.Builder()
                .detectLeakedClosableObjects() // Detect leaked/unclosed SQLite objects
                .penaltyLog()                 // Log violations
                .build()
        )
    }

    private fun triggerSqliteCursorLeak() {
        val db: SQLiteDatabase = context.openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null)
        db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
        db.execSQL("INSERT INTO users (name) VALUES ('Alice'), ('Bob')")

        // Create cursor, and intentionally do not close it
        val cursor = db.rawQuery("SELECT * FROM users", null)
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package org.owasp.mastestapp;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.StrictMode;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;

/* compiled from: MastgTest.kt */
@Metadata(d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\b\u0010\u0005\u001a\u00020\u0006H\u0002J\u0006\u0010\u0007\u001a\u00020\bJ\b\u0010\t\u001a\u00020\u0006H\u0002R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\n"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "enableStrictMode", "", "mastgTest", "", "triggerSqliteCursorLeak", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48)
/* loaded from: classes4.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() {
        enableStrictMode();
        triggerSqliteCursorLeak();
        System.gc();
        return "SUCCESS!!\n\nSQL Cursor leaked.";
    }

    private final void enableStrictMode() {
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedClosableObjects().penaltyLog().build());
    }

    private final void triggerSqliteCursorLeak() {
        SQLiteDatabase db = this.context.openOrCreateDatabase("test.db", 0, null);
        Intrinsics.checkNotNullExpressionValue(db, "openOrCreateDatabase(...)");
        db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
        db.execSQL("INSERT INTO users (name) VALUES ('Alice'), ('Bob')");
        db.rawQuery("SELECT * FROM users", null);
    }
}

Steps

Let's run semgrep rules against the sample code.

../../../../rules/mastg-android-strictmode.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
rules:
  - id: mastg-android-strictmode
    severity: WARNING
    languages:
      - java
    metadata:
      summary: This rule scans uses of StrictMode.
    message: "[MASVS-RESILIENCE] Detected usage of StrictMode"
    patterns:
      - pattern: StrictMode.setVmPolicy(...)
run.sh
1
2
#!/bin/bash
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-strictmode.yml ./MastgTest_reversed.java > output.txt

Observation

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

output.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
┌────────────────┐
 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());

Evaluation

The test fails because the output shows usages of StrictMode.setVmPolicy.