Skip to content

Commit 90860cb

Browse files
chanel-yCopilot
andcommitted
PowerShell: Add insecure random number generator query (CWE-338)
Detects use of Get-Random cmdlet and System.Random class which are not cryptographically secure. Policy: Microsoft.Security.Cryptography.10017 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cccecc4 commit 90860cb

4 files changed

Lines changed: 94 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @name Use of insecure random number generator
3+
* @description Using non-cryptographic random number generators such as Get-Random or System.Random
4+
* for security-sensitive operations can compromise security.
5+
* @kind problem
6+
* @problem.severity error
7+
* @security-severity 7.5
8+
* @precision high
9+
* @id powershell/microsoft/security/insecure-random
10+
* @tags security
11+
* external/cwe/cwe-330
12+
* external/cwe/cwe-338
13+
*/
14+
15+
import powershell
16+
import semmle.code.powershell.ApiGraphs
17+
import semmle.code.powershell.dataflow.DataFlow
18+
19+
/** A call to the `Get-Random` cmdlet. */
20+
class GetRandomCall extends DataFlow::CallNode {
21+
GetRandomCall() { this.matchesName("Get-Random") }
22+
}
23+
24+
/** An instantiation of `System.Random` via `New-Object`. */
25+
class SystemRandomObjectCreation extends DataFlow::ObjectCreationNode {
26+
SystemRandomObjectCreation() {
27+
this.asExpr()
28+
.getExpr()
29+
.(ObjectCreation)
30+
.getAnArgument()
31+
.getValue()
32+
.stringMatches("System.Random")
33+
}
34+
}
35+
36+
/** A call to `[System.Random]::new()` via the API graph. */
37+
class SystemRandomNewCall extends DataFlow::CallNode {
38+
SystemRandomNewCall() {
39+
this = API::getTopLevelMember("system").getMember("random").getMember("new").asCall()
40+
}
41+
}
42+
43+
from DataFlow::Node node, string msg
44+
where
45+
node instanceof GetRandomCall and
46+
msg =
47+
"Use of insecure random number generator 'Get-Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead."
48+
or
49+
node instanceof SystemRandomObjectCreation and
50+
msg =
51+
"Use of insecure random number generator 'System.Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead."
52+
or
53+
node instanceof SystemRandomNewCall and
54+
msg =
55+
"Use of insecure random number generator 'System.Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead."
56+
select node, msg
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.ps1:6:10:6:51 | Call to get-random | Use of insecure random number generator 'Get-Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead. |
2+
| test.ps1:9:16:9:25 | Call to get-random | Use of insecure random number generator 'Get-Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead. |
3+
| test.ps1:12:8:12:31 | Call to new-object | Use of insecure random number generator 'System.Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead. |
4+
| test.ps1:15:9:15:32 | Call to new-object | Use of insecure random number generator 'System.Random'. Use [System.Security.Cryptography.RandomNumberGenerator] instead. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
queries/security/cwe-338/InsecureRandomness.ql
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# ===================================================================
2+
# ========== TRUE POSITIVES (should trigger alert) ==================
3+
# ===================================================================
4+
5+
# --- Case 1: Get-Random cmdlet ---
6+
$token = Get-Random -Minimum 100000 -Maximum 999999 # BAD
7+
8+
# --- Case 2: Get-Random without parameters ---
9+
$randomValue = Get-Random # BAD
10+
11+
# --- Case 3: New-Object System.Random ---
12+
$rng = New-Object System.Random # BAD
13+
14+
# --- Case 4: System.Random with method call ---
15+
$rng2 = New-Object System.Random
16+
$value = $rng2.Next(1, 100) # (The New-Object is the BAD part)
17+
18+
# ===================================================================
19+
# ========== TRUE NEGATIVES (should NOT trigger alert) ==============
20+
# ===================================================================
21+
22+
# --- Safe: Using RandomNumberGenerator ---
23+
$secureRng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
24+
$bytes = New-Object byte[] 32
25+
$secureRng.GetBytes($bytes) # GOOD
26+
27+
# --- Safe: Using RNGCryptoServiceProvider ---
28+
$cspRng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
29+
$secureBytes = New-Object byte[] 16
30+
$cspRng.GetBytes($secureBytes) # GOOD
31+
32+
# --- Safe: Using RandomNumberGenerator static method ---
33+
$randomBytes = [System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32) # GOOD

0 commit comments

Comments
 (0)