From cabf6d056a84c3d35501cfbdc3f11ca16944b274 Mon Sep 17 00:00:00 2001
From: Chanel Young
Date: Thu, 9 Apr 2026 09:32:12 -0700
Subject: [PATCH 1/3] 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>
---
.../security/cwe-326/WeakAsymmetricKey.ql | 79 +++++++++++++++++++
.../WeakAsymmetricKey.expected | 3 +
.../WeakAsymmetricKey/WeakAsymmetricKey.qlref | 1 +
.../cwe-326/WeakAsymmetricKey/test.ps1 | 25 ++++++
4 files changed, 108 insertions(+)
create mode 100644 powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql
create mode 100644 powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected
create mode 100644 powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref
create mode 100644 powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/test.ps1
diff --git a/powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql b/powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql
new file mode 100644
index 000000000000..97e48cd576a7
--- /dev/null
+++ b/powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql
@@ -0,0 +1,79 @@
+/**
+ * @name Weak asymmetric key size
+ * @description Using RSA keys smaller than 2048 bits does not provide adequate security.
+ * @kind problem
+ * @problem.severity error
+ * @security-severity 7.5
+ * @precision high
+ * @id powershell/microsoft/security/weak-asymmetric-key
+ * @tags security
+ * external/cwe/cwe-326
+ */
+
+import powershell
+import semmle.code.powershell.ApiGraphs
+import semmle.code.powershell.dataflow.DataFlow
+
+/**
+ * Holds if `keySize` is below the minimum RSA key size of 2048 bits.
+ */
+bindingset[keySize]
+predicate isWeakKeySize(int keySize) { keySize > 0 and keySize < 2048 }
+
+/**
+ * An RSA.Create(keySize) or RSA::new(keySize) call via the API graph with a weak key size.
+ */
+class WeakRsaCreateCall extends DataFlow::CallNode {
+ int keySize;
+
+ WeakRsaCreateCall() {
+ exists(string method |
+ method = ["create", "new"] and
+ this =
+ API::getTopLevelMember("system")
+ .getMember("security")
+ .getMember("cryptography")
+ .getMember(["rsa", "rsacryptoserviceprovider"])
+ .getMember(method)
+ .asCall()
+ ) and
+ keySize = this.getAnArgument().asExpr().getExpr().(ConstExpr).getValueString().toInt() and
+ isWeakKeySize(keySize)
+ }
+
+ int getKeySize() { result = keySize }
+}
+
+/**
+ * A New-Object RSACryptoServiceProvider(keySize) with a weak key size.
+ */
+class WeakRsaCspCreation extends DataFlow::ObjectCreationNode {
+ int keySize;
+
+ WeakRsaCspCreation() {
+ exists(string objName |
+ objName =
+ this.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString().toLowerCase() and
+ objName =
+ [
+ "system.security.cryptography.rsacryptoserviceprovider",
+ "rsacryptoserviceprovider"
+ ]
+ ) and
+ exists(DataFlow::Node arg |
+ arg = this.getAnArgument() and
+ keySize = arg.asExpr().getExpr().(ConstExpr).getValueString().toInt() and
+ isWeakKeySize(keySize)
+ )
+ }
+
+ int getKeySize() { result = keySize }
+}
+
+from DataFlow::Node node, int keySize
+where
+ exists(WeakRsaCreateCall c | node = c and keySize = c.getKeySize())
+ or
+ exists(WeakRsaCspCreation c | node = c and keySize = c.getKeySize())
+select node,
+ "RSA key size " + keySize.toString() + " bits is below the minimum of 2048 bits."
diff --git a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected
new file mode 100644
index 000000000000..52e8dddddc7f
--- /dev/null
+++ b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected
@@ -0,0 +1,3 @@
+| test.ps1:6:8:6:55 | Call to create | RSA key size 1024 bits is below the minimum of 2048 bits. |
+| test.ps1:9:8:9:54 | Call to create | RSA key size 512 bits is below the minimum of 2048 bits. |
+| test.ps1:12:8:12:73 | Call to new | RSA key size 1024 bits is below the minimum of 2048 bits. |
diff --git a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref
new file mode 100644
index 000000000000..9543ecf74469
--- /dev/null
+++ b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref
@@ -0,0 +1 @@
+queries/security/cwe-326/WeakAsymmetricKey.ql
diff --git a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/test.ps1 b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/test.ps1
new file mode 100644
index 000000000000..12fd3c84331f
--- /dev/null
+++ b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/test.ps1
@@ -0,0 +1,25 @@
+# ===================================================================
+# ========== TRUE POSITIVES (should trigger alert) ==================
+# ===================================================================
+
+# --- Case 1: RSA.Create with 1024-bit key ---
+$rsa = [System.Security.Cryptography.RSA]::Create(1024) # BAD
+
+# --- Case 2: RSA.Create with 512-bit key ---
+$rsa = [System.Security.Cryptography.RSA]::Create(512) # BAD
+
+# --- Case 3: RSACryptoServiceProvider with 1024-bit key via ::new() ---
+$rsa = [System.Security.Cryptography.RSACryptoServiceProvider]::new(1024) # BAD
+
+# ===================================================================
+# ========== TRUE NEGATIVES (should NOT trigger alert) ==============
+# ===================================================================
+
+# --- Safe: RSA.Create with 2048-bit key ---
+$rsa = [System.Security.Cryptography.RSA]::Create(2048) # GOOD
+
+# --- Safe: RSA.Create with 4096-bit key ---
+$rsa = [System.Security.Cryptography.RSA]::Create(4096) # GOOD
+
+# --- Safe: RSA.Create with no argument (default key size) ---
+$rsa = [System.Security.Cryptography.RSA]::Create() # GOOD
From dfd2553aab00faf23f9d07a9763fa8e060866200 Mon Sep 17 00:00:00 2001
From: Chanel Young
Date: Thu, 9 Apr 2026 15:13:56 -0700
Subject: [PATCH 2/3] Weak RSA key size query, docs, test
---
.../security/cryptography/CryptoArtifact.qll | 6 ++
.../cryptography/CryptographyModule.qll | 42 ++++++++++
.../security/cwe-326/WeakAsymmetricKey.ql | 79 -------------------
.../cwe-327/WeakAsymmetricKeySize.qhelp | 40 ++++++++++
.../security/cwe-327/WeakAsymmetricKeySize.ql | 22 ++++++
.../WeakAsymmetricKey/WeakAsymmetricKey.qlref | 1 -
.../WeakAsymmetricKeySize.expected} | 0
.../WeakAsymmetricKeySize.qlref | 1 +
.../WeakAsymmetricKeySize}/test.ps1 | 0
9 files changed, 111 insertions(+), 80 deletions(-)
delete mode 100644 powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql
create mode 100644 powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp
create mode 100644 powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.ql
delete mode 100644 powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref
rename powershell/ql/test/query-tests/security/{cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected => cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.expected} (100%)
create mode 100644 powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref
rename powershell/ql/test/query-tests/security/{cwe-326/WeakAsymmetricKey => cwe-327/WeakAsymmetricKeySize}/test.ps1 (100%)
diff --git a/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptoArtifact.qll b/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptoArtifact.qll
index 0aa91bff8c43..37266949c5ae 100644
--- a/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptoArtifact.qll
+++ b/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptoArtifact.qll
@@ -36,3 +36,9 @@ abstract class BlockMode extends CryptographicAlgorithm {
else result = unknownAlgorithm()
}
}
+
+abstract class AsymmetricKeyCreation extends CryptographicArtifact {
+ abstract string getAlgorithmName();
+
+ abstract int getKeySize();
+}
diff --git a/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptographyModule.qll b/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptographyModule.qll
index 0e6b2a434733..bd3362dadcdb 100644
--- a/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptographyModule.qll
+++ b/powershell/ql/lib/semmle/code/powershell/security/cryptography/CryptographyModule.qll
@@ -194,3 +194,45 @@ class CipherBlockModeEnum extends BlockMode {
override string getName() { result = modeName }
}
+
+class RsaCreateKeyCreation extends AsymmetricKeyCreation, DataFlow::CallNode {
+ int keySize;
+
+ RsaCreateKeyCreation() {
+ exists(string method |
+ method = ["create", "new"] and
+ this =
+ API::getTopLevelMember("system")
+ .getMember("security")
+ .getMember("cryptography")
+ .getMember(["rsa", "rsacryptoserviceprovider"])
+ .getMember(method)
+ .asCall()
+ ) and
+ keySize = this.getAnArgument().asExpr().getExpr().(ConstExpr).getValueString().toInt()
+ }
+
+ override string getAlgorithmName() { result = "rsa" }
+
+ override int getKeySize() { result = keySize }
+}
+
+class RsaCspObjectKeyCreation extends AsymmetricKeyCreation, CryptoAlgorithmObjectCreation {
+ int keySize;
+
+ RsaCspObjectKeyCreation() {
+ objectName =
+ [
+ "system.security.cryptography.rsacryptoserviceprovider",
+ "rsacryptoserviceprovider"
+ ] and
+ exists(DataFlow::Node arg |
+ arg = this.getAnArgument() and
+ keySize = arg.asExpr().getExpr().(ConstExpr).getValueString().toInt()
+ )
+ }
+
+ override string getAlgorithmName() { result = "rsa" }
+
+ override int getKeySize() { result = keySize }
+}
diff --git a/powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql b/powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql
deleted file mode 100644
index 97e48cd576a7..000000000000
--- a/powershell/ql/src/queries/security/cwe-326/WeakAsymmetricKey.ql
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @name Weak asymmetric key size
- * @description Using RSA keys smaller than 2048 bits does not provide adequate security.
- * @kind problem
- * @problem.severity error
- * @security-severity 7.5
- * @precision high
- * @id powershell/microsoft/security/weak-asymmetric-key
- * @tags security
- * external/cwe/cwe-326
- */
-
-import powershell
-import semmle.code.powershell.ApiGraphs
-import semmle.code.powershell.dataflow.DataFlow
-
-/**
- * Holds if `keySize` is below the minimum RSA key size of 2048 bits.
- */
-bindingset[keySize]
-predicate isWeakKeySize(int keySize) { keySize > 0 and keySize < 2048 }
-
-/**
- * An RSA.Create(keySize) or RSA::new(keySize) call via the API graph with a weak key size.
- */
-class WeakRsaCreateCall extends DataFlow::CallNode {
- int keySize;
-
- WeakRsaCreateCall() {
- exists(string method |
- method = ["create", "new"] and
- this =
- API::getTopLevelMember("system")
- .getMember("security")
- .getMember("cryptography")
- .getMember(["rsa", "rsacryptoserviceprovider"])
- .getMember(method)
- .asCall()
- ) and
- keySize = this.getAnArgument().asExpr().getExpr().(ConstExpr).getValueString().toInt() and
- isWeakKeySize(keySize)
- }
-
- int getKeySize() { result = keySize }
-}
-
-/**
- * A New-Object RSACryptoServiceProvider(keySize) with a weak key size.
- */
-class WeakRsaCspCreation extends DataFlow::ObjectCreationNode {
- int keySize;
-
- WeakRsaCspCreation() {
- exists(string objName |
- objName =
- this.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString().toLowerCase() and
- objName =
- [
- "system.security.cryptography.rsacryptoserviceprovider",
- "rsacryptoserviceprovider"
- ]
- ) and
- exists(DataFlow::Node arg |
- arg = this.getAnArgument() and
- keySize = arg.asExpr().getExpr().(ConstExpr).getValueString().toInt() and
- isWeakKeySize(keySize)
- )
- }
-
- int getKeySize() { result = keySize }
-}
-
-from DataFlow::Node node, int keySize
-where
- exists(WeakRsaCreateCall c | node = c and keySize = c.getKeySize())
- or
- exists(WeakRsaCspCreation c | node = c and keySize = c.getKeySize())
-select node,
- "RSA key size " + keySize.toString() + " bits is below the minimum of 2048 bits."
diff --git a/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp b/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp
new file mode 100644
index 000000000000..7cb6a223fcf5
--- /dev/null
+++ b/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp
@@ -0,0 +1,40 @@
+
+
+
+
+ Modern encryption relies on it being computationally infeasible to break the cipher and
+ decode a message without the key. As computational power increases, the ability to break
+ ciphers grows and keys need to become larger.
+
+
+ RSA keys smaller than 2048 bits are considered weak and can potentially be broken using
+ modern hardware. Using such keys compromises the confidentiality and integrity of
+ encrypted data.
+
+
+
+
+
+ Use an RSA key size of at least 2048 bits. For long-term security, consider using
+ 4096-bit keys.
+
+
+ When calling [System.Security.Cryptography.RSA]::Create() or creating an
+ RSACryptoServiceProvider, always specify a key size of 2048 or greater.
+
+
+
+
+
+ The following example shows the creation of an RSA key with only 1024 bits, which is
+ considered weak:
+
+
+
+
+
+ NIST, SP 800-131A: Transitioning the Use of Cryptographic Algorithms and Key Lengths.
+ Wikipedia: RSA cryptosystem.
+ CWE-327: Use of a Broken or Risky Cryptographic Algorithm.
+
+
diff --git a/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.ql b/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.ql
new file mode 100644
index 000000000000..0e40edfb6b56
--- /dev/null
+++ b/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.ql
@@ -0,0 +1,22 @@
+/**
+ * @name Weak asymmetric key size
+ * @description Using RSA keys smaller than 2048 bits does not provide adequate security.
+ * @kind problem
+ * @problem.severity error
+ * @security-severity 7.5
+ * @precision high
+ * @id powershell/weak-asymmetric-key-size
+ * @tags security
+ * external/cwe/cwe-327
+ */
+
+import powershell
+import semmle.code.powershell.dataflow.DataFlow
+import semmle.code.powershell.security.cryptography.Concepts
+
+from AsymmetricKeyCreation keyCreation, int keySize
+where
+ keySize = keyCreation.getKeySize() and
+ keySize < 2048
+select keyCreation,
+ "RSA key size " + keySize.toString() + " bits is below the minimum of 2048 bits."
diff --git a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref b/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref
deleted file mode 100644
index 9543ecf74469..000000000000
--- a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.qlref
+++ /dev/null
@@ -1 +0,0 @@
-queries/security/cwe-326/WeakAsymmetricKey.ql
diff --git a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.expected
similarity index 100%
rename from powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/WeakAsymmetricKey.expected
rename to powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.expected
diff --git a/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref
new file mode 100644
index 000000000000..67e632a55e00
--- /dev/null
+++ b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/WeakAsymmetricKeySize.qlref
@@ -0,0 +1 @@
+queries/security/cwe-327/WeakAsymmetricKeySize.ql
diff --git a/powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/test.ps1 b/powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/test.ps1
similarity index 100%
rename from powershell/ql/test/query-tests/security/cwe-326/WeakAsymmetricKey/test.ps1
rename to powershell/ql/test/query-tests/security/cwe-327/WeakAsymmetricKeySize/test.ps1
From 2e342de706b075dfe4d23224b09e1df12628e4a7 Mon Sep 17 00:00:00 2001
From: Chanel Young
Date: Thu, 9 Apr 2026 15:17:45 -0700
Subject: [PATCH 3/3] remove example from qhelp
---
.../queries/security/cwe-327/WeakAsymmetricKeySize.qhelp | 8 --------
1 file changed, 8 deletions(-)
diff --git a/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp b/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp
index 7cb6a223fcf5..c7b5aa54f19e 100644
--- a/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp
+++ b/powershell/ql/src/queries/security/cwe-327/WeakAsymmetricKeySize.qhelp
@@ -24,14 +24,6 @@
-
-
- The following example shows the creation of an RSA key with only 1024 bits, which is
- considered weak:
-
-
-
-
NIST, SP 800-131A: Transitioning the Use of Cryptographic Algorithms and Key Lengths.
Wikipedia: RSA cryptosystem.