Skip to content

Insecure Randomness

What does this mean ?

When a function that can provide predictable values is utilized as a source of randomness in a security-sensitive situation, insecure randomness mistakes arise. Standard pseudo-random number generators are vulnerable to cryptographic attacks.

What can happen ?

Using a cryptographically weak pseudo-random number generator to create a security-sensitive value, such as a password, allows an attacker to anticipate the result more easily.

Recommendation

  • Use a well-vetted method that experts in the area currently regard to be strong and select well-tested implementations with suitable length seeds.

Sample Code

Vulnerable :

using System;

class ExampleClass
{
    public void ExampleMethod(Random random)
    {
        var sensitiveVariable = random.Next();
    }
}

Non Vulnerable :

using System;
using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(RandomNumberGenerator randomNumberGenerator, int toExclusive)
    {
        var sensitiveVariable = randomNumberGenerator.GetInt32(toExclusive);
    }
}

Vulnerable :

Import java.util.Random
public static int generateRandomInt(int upperRange)
{
  Random random = new Random();
  return random.nextInt(upperRange);
}

Non Vulnerable :

Import java.security.SecureRandom
public static int generateRandom(int maximumValue)
{
  SecureRandom ranGen = new SecureRandom();
  return ranGen.nextInt(maximumValue);
}

Vulnerable :

$random = rand();
$random2 = mt_rand(0, 99);

Non Vulnerable :

$randomInt = random_int(0,99); // Compliant; generates a cryptographically secure random integer

Vulnerable :

package main

import (
    "math/rand"
)

var characterset = []rune("z9%jAqEXAAepFU$xj2YakQwdCvD%FHtd+9$Wej^!rzUr5M")

func generatePassword() string {
    str := make([]rune, 20)
    for i := range str {
        str[i] = characterset[rand.Intn(len(characterset))]
    }
    return string(str)
}

Non Vulnerable :

package main

import (
    "crypto/rand"
    "math/big"
)

func generatePassword() string {
    str := make([]rune, 20)
    for i := range str {
        index, err := rand.Int(rand.Reader, big.NewInt(int64(len(characterset))))
        if err != nil {
            // handle err
        }
        str[i] = characterset[index.Int64()]
    }
    return string(str)
}

References