Insecure Randomness
ID |
csharp.insecure_randomness |
Severity |
high |
Resource |
Predictability |
Language |
CSharp |
Tags |
CWE:330, CWE:332, CWE:336, CWE:337, CWE:338, NIST.SP.800-53, OWASP:2021:A2, PCI-DSS:6.5.3 |
Description
Use of cryptographically weak pseudo-random number generator (PRNG).
Insecure randomness errors occur when a function that can produce predictable values is used as a source of randomness in a security-sensitive context.
Computers are unable to produce true randomness. Pseudo-Random Number Generators (PRNGs) approximate randomness algorithmically, starting with a seed from which subsequent values are calculated.
There are two types of PRNGs: statistical and cryptographic. Statistical PRNGs provide useful statistical properties, but their output is predictable and forms an easy to reproduce numeric stream, unsuitable for use in cases where security depends on generated values being unpredictable.
Cryptographic PRNGs address this problem by generating output that is more difficult to predict. For a value to be cryptographically secure, it must be highly improbable for an attacker to distinguish between it and a truly random value. In general, if a PRNG algorithm is not advertised as being cryptographically secure, then it is probably a statistical PRNG and should not be used in security-sensitive contexts, where its use can lead to serious vulnerabilities such as easy-to-guess temporary passwords, predictable cryptographic keys, session hijacking, and DNS spoofing.
Rationale
Randomness is often utilized in software applications for generating keys, tokens, session identifiers, and more. However, not all random number generators are suitable for security-sensitive tasks.
System.Random
class, for example, does not provide the unpredictability needed for secure random number generation, as its algorithm and seed value can lead to predictable sequences.
Using System.Random
in a security context can result in serious vulnerabilities like predictability of keys, which attackers could exploit. Consider the following example:
using System;
public class TokenGenerator
{
// Insecure: Predictable token generation
public string GenerateToken()
{
Random random = new Random();
byte[] bytes = new byte[24];
// VULNERABLE - Insecure random number generator
// used in a cryptographic context
random.NextBytes(bytes);
return Convert.ToHexString(bytes);
}
}
In this example, tokens generated using System.Random
are vulnerable to prediction, as the randomness source is not sufficiently secure for generating tokens used in security contexts.
Random
and other pseudorandom generators should not be used for cryptographic tasks. They can be used for other purposes, anyway, like simulation, games, visualizations, etc.
Remediation
To remediate the vulnerabilities related to insecure randomness in C# software, developers should transition to using the System.Security.Cryptography.SecureRandom
class, which is designed to provide a cryptographically strong random number generator.
using System;
using System.Security.Cryptography;
public string GenerateSecureToken()
{
byte[] bytes = new byte[24];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(bytes);
return Convert.ToHexString(bytes);
}
}
Prefer the new RandomNumberGenerator
over the legacy RNGCryptoServiceProvider
, when possible.
There is a deprecated RandomNumberGenerator.Create(string) method where a string with the random number generator to use can be passed. Cryptographic factory methods accepting an algorithm name are obsolete. Use the parameterless RandomNumberGenerator.Create() method instead.
|
Configuration
The rule has the following configurable parameters:
-
checkSecurityContext
, that indicates if the detector should raise issues that are not located under a security context. When this is set to false, the issues not located under a security context will still be reported but withINFO
severity. -
securityContextPattern
, the pattern used to match the code units (like functions) that are related to a security context.
References
-
CWE-338 : Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG).
-
CWE-330 : Use of Insufficiently Random Values
-
CWE-332 : Insufficient Entropy in PRNG
-
CWE-336 : Same Seed in Pseudo-Random Number Generator (PRNG)
-
CWE-337 : Predictable Seed in Pseudo-Random Number Generator (PRNG)
-
OWASP - Top 10 2021 - A2 : Cryptographic Failures