Skip to content
Last updated: July 10, 2024

MASTG-DEMO-0007: Common Uses of Insecure Random APIs

Content in BETA

This content is in beta and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Sample

 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
package org.owasp.mastestapp

import android.content.Context
import java.util.Random
import java.lang.*
import java.security.SecureRandom

class MastgTest (private val context: Context){

    fun mastgTest(): String {

        // FAIL: [android-insecure-random-use] The app insecurely uses random numbers for generating authentication tokens.
        val random1 = Random().nextDouble()

        // FAIL: [android-insecure-random-use] The title of the function indicates that it generates a random number, but it is unclear how it is actually used in the rest of the app. Review any calls to this function to ensure that the random number is not used in a security-relevant context.
        val random2 = 1 + Math.random()

        val length = 16
        val characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
        val random = Random()
        val password = StringBuilder(length)

        for (i in 0 until length) {
            // FAIL: [android-insecure-random-use] The app insecurely uses random numbers for generating passwords, which is a security-relevant context.
            password.append(characters[random.nextInt(characters.length)])
        }

        val random3 = password.toString()

        // PASS: [android-insecure-random-use] The app uses a secure random number generator.

        val random4 = SecureRandom().nextInt(21)

        return "Generated random numbers:\n$random1 \n$random2 \n$random3 \n$random4"
    }

}
 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
package org.owasp.mastestapp;

import android.content.Context;
import java.security.SecureRandom;
import java.util.Random;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;

/* 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\u0002\n\u0002\u0010\u000e\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0006\u0010\u0005\u001a\u00020\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\u0007"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "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() {
        double random1 = new Random().nextDouble();
        double random2 = 1 + Math.random();
        Random random = new Random();
        StringBuilder password = new StringBuilder(16);
        for (int i = 0; i < 16; i++) {
            password.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".length())));
        }
        String random3 = password.toString();
        Intrinsics.checkNotNullExpressionValue(random3, "toString(...)");
        int random4 = new SecureRandom().nextInt(21);
        return "Generated random numbers:\n" + random1 + " \n" + random2 + " \n" + random3 + " \n" + random4;
    }
}

Steps

Let's run our semgrep rule against the sample code.

../../../../rules/mastg-android-insecure-random-use.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
rules:
  - id: mastg-android-insecure-random-use
    severity: WARNING
    languages:
      - java
    metadata:
      summary: This rule looks for common patterns including classes and methods.
      original_source: https://github.com/mindedsecurity/semgrep-rules-android-security/blob/main/rules/crypto/mstg-crypto-6.yaml
    message: "[MASVS-CRYPTO-1] The application makes use of an insecure random number generator."

    pattern-either:
        - patterns:
            - pattern-inside: $M(...){ ... }
            - pattern-either:
                - pattern: Math.random(...)
                - pattern: (java.util.Random $X).$Y(...)
run.sh
1
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-insecure-random-use.yaml ./MastgTest_reversed.java --text -o output.txt

Observation

The rule has identified five instances in the code file where an insecure random number generator is used. The specified line numbers can be located in the original code for further investigation and remediation.

output.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
┌─────────────────┐
 3 Code Findings 
└─────────────────┘

    MastgTest_reversed.java 
       rules.mastg-android-insecure-random-use                                              
          [MASVS-CRYPTO-1] The application makes use of an insecure random number generator.

           22 double random1 = new Random().nextDouble();
            ⋮┆----------------------------------------
           23 double random2 = 1 + Math.random();
            ⋮┆----------------------------------------
           27  ... random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".length()))); ... 
            [shortened a long line from output, adjust with --max-chars-per-line]

Evaluation

Review each of the reported instances.

  • Line 12 seems to be used to generate random numbers for security purposes, in this case for generating authentication tokens.
  • Line 17 is part of the function get_random. Review any calls to this function to ensure that the random number is not used in a security-relevant context.
  • Line 27 is part of the password generation function which is a security-critical operation.

Note that line 37 did not trigger the rule because the random number is generated using SecureRandom which is a secure random number generator.