Skip to content

Commit cabf6d0

Browse files
chanel-yCopilot
andcommitted
Add weak asymmetric key size detection query for PowerShell
Detects RSA key sizes below 2048 bits via RSA.Create(), RSA::new(), and RSACryptoServiceProvider::new() patterns. Covers: Cryptography.10012 (CWE-326) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cccecc4 commit cabf6d0

4 files changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* @name Weak asymmetric key size
3+
* @description Using RSA keys smaller than 2048 bits does not provide adequate security.
4+
* @kind problem
5+
* @problem.severity error
6+
* @security-severity 7.5
7+
* @precision high
8+
* @id powershell/microsoft/security/weak-asymmetric-key
9+
* @tags security
10+
* external/cwe/cwe-326
11+
*/
12+
13+
import powershell
14+
import semmle.code.powershell.ApiGraphs
15+
import semmle.code.powershell.dataflow.DataFlow
16+
17+
/**
18+
* Holds if `keySize` is below the minimum RSA key size of 2048 bits.
19+
*/
20+
bindingset[keySize]
21+
predicate isWeakKeySize(int keySize) { keySize > 0 and keySize < 2048 }
22+
23+
/**
24+
* An RSA.Create(keySize) or RSA::new(keySize) call via the API graph with a weak key size.
25+
*/
26+
class WeakRsaCreateCall extends DataFlow::CallNode {
27+
int keySize;
28+
29+
WeakRsaCreateCall() {
30+
exists(string method |
31+
method = ["create", "new"] and
32+
this =
33+
API::getTopLevelMember("system")
34+
.getMember("security")
35+
.getMember("cryptography")
36+
.getMember(["rsa", "rsacryptoserviceprovider"])
37+
.getMember(method)
38+
.asCall()
39+
) and
40+
keySize = this.getAnArgument().asExpr().getExpr().(ConstExpr).getValueString().toInt() and
41+
isWeakKeySize(keySize)
42+
}
43+
44+
int getKeySize() { result = keySize }
45+
}
46+
47+
/**
48+
* A New-Object RSACryptoServiceProvider(keySize) with a weak key size.
49+
*/
50+
class WeakRsaCspCreation extends DataFlow::ObjectCreationNode {
51+
int keySize;
52+
53+
WeakRsaCspCreation() {
54+
exists(string objName |
55+
objName =
56+
this.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString().toLowerCase() and
57+
objName =
58+
[
59+
"system.security.cryptography.rsacryptoserviceprovider",
60+
"rsacryptoserviceprovider"
61+
]
62+
) and
63+
exists(DataFlow::Node arg |
64+
arg = this.getAnArgument() and
65+
keySize = arg.asExpr().getExpr().(ConstExpr).getValueString().toInt() and
66+
isWeakKeySize(keySize)
67+
)
68+
}
69+
70+
int getKeySize() { result = keySize }
71+
}
72+
73+
from DataFlow::Node node, int keySize
74+
where
75+
exists(WeakRsaCreateCall c | node = c and keySize = c.getKeySize())
76+
or
77+
exists(WeakRsaCspCreation c | node = c and keySize = c.getKeySize())
78+
select node,
79+
"RSA key size " + keySize.toString() + " bits is below the minimum of 2048 bits."
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.ps1:6:8:6:55 | Call to create | RSA key size 1024 bits is below the minimum of 2048 bits. |
2+
| test.ps1:9:8:9:54 | Call to create | RSA key size 512 bits is below the minimum of 2048 bits. |
3+
| test.ps1:12:8:12:73 | Call to new | RSA key size 1024 bits is below the minimum of 2048 bits. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
queries/security/cwe-326/WeakAsymmetricKey.ql
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# ===================================================================
2+
# ========== TRUE POSITIVES (should trigger alert) ==================
3+
# ===================================================================
4+
5+
# --- Case 1: RSA.Create with 1024-bit key ---
6+
$rsa = [System.Security.Cryptography.RSA]::Create(1024) # BAD
7+
8+
# --- Case 2: RSA.Create with 512-bit key ---
9+
$rsa = [System.Security.Cryptography.RSA]::Create(512) # BAD
10+
11+
# --- Case 3: RSACryptoServiceProvider with 1024-bit key via ::new() ---
12+
$rsa = [System.Security.Cryptography.RSACryptoServiceProvider]::new(1024) # BAD
13+
14+
# ===================================================================
15+
# ========== TRUE NEGATIVES (should NOT trigger alert) ==============
16+
# ===================================================================
17+
18+
# --- Safe: RSA.Create with 2048-bit key ---
19+
$rsa = [System.Security.Cryptography.RSA]::Create(2048) # GOOD
20+
21+
# --- Safe: RSA.Create with 4096-bit key ---
22+
$rsa = [System.Security.Cryptography.RSA]::Create(4096) # GOOD
23+
24+
# --- Safe: RSA.Create with no argument (default key size) ---
25+
$rsa = [System.Security.Cryptography.RSA]::Create() # GOOD

0 commit comments

Comments
 (0)