Skip to content

Commit 5a048fe

Browse files
committed
CWE-330: Use of Insufficiently Random Values Documentation
Signed-off-by: ebakrra <[email protected]>
1 parent 437708f commit 5a048fe

File tree

3 files changed

+106
-9
lines changed

3 files changed

+106
-9
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# CWE-330: Use of Insufficiently Random Values
2+
3+
When programming cryptographic functions ensure to use a Pseudo-Random Number Generator (PRNG) source that is random enough to be suitable for encryption.
4+
5+
Certain algorithms can create sequences of numbers that approximate random distributions. These algorithms, known as pseudorandom number generators (PRNGs) are numbers generated by a computational process and appear random, even though they are produced by a deterministic algorithm. This means that, unlike truly random numbers, which are inherently unpredictable, pseudorandom numbers are generated in a predictable sequence as long as you know the starting point, or the seed, and the algorithm used to generate them.
6+
7+
PRNGs suitable for encryption must mix non-computational sources such as a mouse, keyboard, or even Lava Lamps [LavaRnd] to be random enough for encryption.
8+
9+
Python's random module is a standard library module that provides functions to generate pseudorandom numbers for various distributions. This module however can lead to a vulnerability due to its predictability. The random module is based on the Mersenne Twister [Mersenne Twister - an overview | ScienceDirect Topics], which is a deterministic algorithm, hence, if an attacker knows or can guess the seed value, they can predict the entire sequence of the pseudorandom numbers. This also means that if two Random class objects are created using an identical seed, they will generate the same sequence of numbers, regardless of the Python environment.
10+
11+
Therefore, the random module is unsuitable for applications requiring high security as it does not incorporate cryptographic randomness, which means it is not resistant to reverse engineering. Its limited entropy makes it easier for attackers to deduce the internal state of the generator and predict future outputs.
12+
13+
Instead, for generating random numbers, it is recommended to use a more robust option, like Python's secrets module.
14+
15+
## Non-compliant Code Example
16+
17+
In `noncompliant01.py`, we generate a random web token using Python's random module. This makes the token predictable and vulnerable to exploitation, as the sequence of numbers is always the same for any specified seed value.
18+
19+
*[noncompliant01.py](noncompliant01.py):*
20+
21+
```py
22+
# SPDX-FileCopyrightText: OpenSSF project contributors
23+
# SPDX-License-Identifier: MIT
24+
""" Non-compliant Code Example """
25+
import random
26+
27+
28+
def generate_web_token():
29+
"""Poor random number generator"""
30+
return random.randrange(int("1" + "0" * 31), int("9" * 32), 1)
31+
32+
33+
#####################
34+
# attempting to exploit above code example
35+
#####################
36+
TOKEN = generate_web_token()
37+
print(f"Your insecure token is: {TOKEN}")
38+
```
39+
40+
## Compliant Code Example
41+
42+
[!NOTE]
43+
> The `secrets` module `os.urandom()` is called by `"secrets.token_urlsafe()"` causing its cryptographic strength to depend on the operating system and its entropy sources.
44+
Pure randomness can not be produced in software alone [[cloudflare 2017]](https://blog.cloudflare.com/randomness-101-lavarand-in-production/).
45+
46+
The `compliant01.py` solution uses the secrets module to generate the random numbers. The secrets module provides access to the most secure source of randomness that the os provides through `os.urandom()`.
47+
48+
*[compliant01.py](compliant01.py):*
49+
50+
```py
51+
# SPDX-FileCopyrightText: OpenSSF project contributors
52+
# SPDX-License-Identifier: MIT
53+
""" Compliant Code Example """
54+
import secrets
55+
56+
57+
def generate_web_token():
58+
"""Better cryptographic number generator"""
59+
return secrets.token_urlsafe()
60+
61+
62+
#####################
63+
# attempting to exploit above code example
64+
#####################
65+
TOKEN = generate_web_token()
66+
print(f"Your secure token is: {TOKEN}")
67+
```
68+
69+
## Automated Detection
70+
71+
|Tool|Version|Checker|Description|
72+
|:----|:----|:----|:----|
73+
|[sonarlint](https://www.sonarsource.com/products/sonarlint/)|9.0.0.75308|SonarQube 9.7+|When in Connected mode Sonarlint can be configured to detect the Sonar rule ["Using pseudorandom number generators (PRNGs) is security-sensitive"](https://rules.sonarsource.com/python/RSPEC-2245/)|
74+
|[Bandit](https://bandit.readthedocs.io/en/latest/)|1.7.4|[B311](https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html?highlight=B311#b311-random)|Standard pseudo-random generators are not suitable for security/cryptographic purposes.|
75+
76+
## Related Guidelines
77+
78+
|||
79+
|:---|:---|
80+
|[SEI CERT C Coding Standard](https://wiki.sei.cmu.edu/confluence/display/c/SEI+CERT+C+Coding+Standard)|[MSC30-C. Do not use the rand() function for generating pseudorandom numbers](https://wiki.sei.cmu.edu/confluence/display/c/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers)|
81+
|[SEI CERT C++ Coding Standard](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682)|[MSC50-CPP. Do not use std::rand() for generating pseudorandom numbers](https://wiki.sei.cmu.edu/confluence/display/cplusplus/MSC50-CPP.+Do+not+use+std%3A%3Arand%28%29+for+generating+pseudorandom+numbers)|
82+
|[The CERT C++ Secure Coding Standard](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682) |[VOID FLP02-CPP. Avoid using floating point numbers when precise computation is needed](https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046687)|
83+
|[SEI CERT Java Coding Standards](https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards)| [MSC02-J. Generate strong random numbers](https://wiki.sei.cmu.edu/confluence/display/java/MSC02-J.+Generate+strong+random+numbers)|
84+
|MITRE CWE Pillar| [CWE-693: Protection Mechanism Failure (4.12) (mitre.org)](https://cwe.mitre.org/data/definitions/693.html)|
85+
|MITRE CWE Class|[CWE-330, Use of Insufficiently Random Values](http://cwe.mitre.org/data/definitions/330.html)|
86+
87+
## Biblography
88+
89+
|||
90+
|:---|:---|
91+
|[[Python docs - random]](https://docs.python.org/3/library/random.html)|Python Software Foundation. (2023). random- Generate pseudo-random numbers[online].Available from: [Python docs - random](https://docs.python.org/3/library/random.html) [accessed 23 August 2023].|
92+
|[[Python docs - secrets]](https://docs.python.org/3/library/secrets.html)|Python Software Foundation. (2023). secrets - Generate secure random numbers for managing secrets [online]. Available from: [Python docs - secrets](https://docs.python.org/3/library/secrets.html) [accessed 23 August 2023].|
93+
|[[Python docs - os]](https://docs.python.org/3/library/os.html)|Python Software Foundation. (2023). os - Miscellaneous operating system interfaces [online].Available from: [Python docs - os](https://docs.python.org/3/library/os.html) [accessed 23 August 2023].|
94+
|[sonar docs - Using pseudorandom number generators (PRNGs) is security-sensitive](https://rules.sonarsource.com/python/RSPEC-2245/)|Sonar Rules - Using pseudorandom number generators (PRNGs) is security-sensitive. Available from [Using pseudorandom number generators (PRNGs) is security-sensitive](https://rules.sonarsource.com/python/RSPEC-2245/) [accessed 7 September 2023].|
95+
|[[Cloudflare 2017]](https://blog.cloudflare.com/)| [Randomness 101: LavaRand in Production (cloudflare.com)](https://blog.cloudflare.com/randomness-101-lavarand-in-production/)|
96+
|LavaRnd|[LavaRnd](https://www.lavarand.org/)|
97+
|[Science Direct - Mersenne Twister]|[Mersenne Twister - an overview / ScienceDirect Topics](https://www.sciencedirect.com/topics/computer-science/mersenne-twister)|

docs/Secure-Coding-Guide-for-Python/CWE-693/CWE-330/compliant01.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
# SPDX-License-Identifier: MIT
33
""" Compliant Code Example """
44
import secrets
5-
6-
5+
6+
77
def generate_web_token():
88
"""Better cryptographic number generator"""
99
return secrets.token_urlsafe()
10-
11-
10+
11+
1212
#####################
1313
# attempting to exploit above code example
1414
#####################
1515
TOKEN = generate_web_token()
16-
print(f"Your secure tokens is: {TOKEN}")
16+
print(f"Your secure token is: {TOKEN}")

docs/Secure-Coding-Guide-for-Python/CWE-693/CWE-330/noncompliant01.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
# SPDX-License-Identifier: MIT
33
""" Non-compliant Code Example """
44
import random
5-
6-
5+
6+
77
def generate_web_token():
88
"""Poor random number generator"""
99
return random.randrange(int("1" + "0" * 31), int("9" * 32), 1)
10-
11-
10+
11+
1212
#####################
1313
# attempting to exploit above code example
1414
#####################

0 commit comments

Comments
 (0)