Main Content

CWE Rule 337

Predictable Seed in Pseudo-Random Number Generator (PRNG)

Since R2024a

Description

Rule Description

A Pseudo-Random Number Generator (PRNG) is initialized from a predictable seed, such as the process ID or system time.

Polyspace Implementation

The rule checker checks for Predictable random output from predictable seed.

Examples

expand all

Issue

This issue occurs when you use standard random number generator functions with a nonconstant but predictable seed. Examples of predictable seed generators are time, gettimeofday, and getpid.

The checker detects this issue with the following random number generator functions:

  • C Standard Library functions such as srand, srandom and initstate

  • C++ Standard Library functions such as std::linear_congruential_engine<>::seed() and std::mersenne_twister_engine<>::seed() (and also the constructors of these class templates)

Risk

When you use predictable seed values for random number generation, your random numbers are also predictable. A hacker can disrupt your program if they know how your program behaves.

Fix

You can use a different function to generate less predictable seeds.

You can also use a different random number generator that does not require a seed. For example, the Windows® API function rand_s seeds itself by default. It uses information from the entire system, for example, system time, thread ids, system counter, and memory clusters. This information is more random and a user cannot access this information.

Some standard random routines are inherently cryptographically weak, and should not be used for security purposes.

Example — Seed as an Argument
#include <stdlib.h>
#include <time.h>

void seed_rng(int seed)
{
    srand(seed); //Noncompliant
}

int generate_num(void)
{
    seed_rng(time(NULL) + 3);
    /* ... */
}

This example uses srand to start the random number generator with seed as the seed. However, seed is predictable because the function time generates it. So, an attacker can predict the random numbers generated by srand.

Correction — Use Different Random Number Generator

One possible correction is to use a random number generator that does not require a seed. This example uses rand_s.


#define _CRT_RAND_S

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int generate_num(void)
{
    unsigned int number;
    errno_t err;
    err = rand_s(&number);

    if(err != 0)
    {
        return number;
    }
    else
    {
        return err;
    }
}

Check Information

Category: Others

Version History

Introduced in R2024a