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.