diff --git a/ql/src/experimental/CWE-326/InsufficientKeySize.qhelp b/ql/src/experimental/CWE-326/InsufficientKeySize.qhelp new file mode 100644 index 00000000000..c18341ca922 --- /dev/null +++ b/ql/src/experimental/CWE-326/InsufficientKeySize.qhelp @@ -0,0 +1,50 @@ + + + +

+ Incorrect uses of encryption algorithms may result in sensitive data exposure, + key leakage, broken authentication, insecure session, and spoofing attacks. +

+ +
+ + +

+ Ensure that you use a strong key with a recommended bit size. + For RSA encryption the minimum size is 2048 bits. +

+ +
+ + +

+ The following code uses RSA encryption with insufficient key size. +

+ + + +

+ In the example below the key size is set to 2048 bits. +

+ + + +
+ + +
  • OWASP: Cryptographic Storage Cheat Sheet. +
  • +
  • Wikipedia: Cryptographically Strong Algorithms. +
  • +
  • Wikipedia: Strong Cryptography Examples. +
  • +
  • NIST, FIPS 140 Annex a: Approved Security Functions.
  • +
  • NIST, SP 800-131A: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths.
  • +
    + +
    diff --git a/ql/src/experimental/CWE-326/InsufficientKeySize.ql b/ql/src/experimental/CWE-326/InsufficientKeySize.ql new file mode 100644 index 00000000000..ab5637f2914 --- /dev/null +++ b/ql/src/experimental/CWE-326/InsufficientKeySize.ql @@ -0,0 +1,32 @@ +/** + * @name Use of a weak cryptographic key + * @description Using weak cryptographic key can allow an attacker to compromise security. + * @kind path-problem + * @problem.severity error + * @id go/weak-crypto-key + * @tags security + * external/cwe/cwe-326 + */ + +import go +import DataFlow::PathGraph + +/** + * RSA key length data flow tracking configuration. + */ +class RsaKeyTrackingConfiguration extends DataFlow::Configuration { + RsaKeyTrackingConfiguration() { this = "RsaKeyTrackingConfiguration" } + + override predicate isSource(DataFlow::Node source) { source.getIntValue() < 2048 } + + override predicate isSink(DataFlow::Node sink) { + exists(DataFlow::CallNode c | + sink = c.getArgument(1) and + c.getTarget().hasQualifiedName("crypto/rsa", "GenerateKey") + ) + } +} + +from RsaKeyTrackingConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) +select sink, source, sink, "The size of this RSA key should be at least 2048 bits." diff --git a/ql/src/experimental/CWE-326/InsufficientKeySizeBad.go b/ql/src/experimental/CWE-326/InsufficientKeySizeBad.go new file mode 100644 index 00000000000..22682bcdef3 --- /dev/null +++ b/ql/src/experimental/CWE-326/InsufficientKeySizeBad.go @@ -0,0 +1,16 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" + "fmt" +) + +func main() { + //Generate Private Key + pvk, err := rsa.GenerateKey(rand.Reader, 1024) + if err != nil { + fmt.Println(err) + } + fmt.Println(pvk) +} diff --git a/ql/src/experimental/CWE-326/InsufficientKeySizeGood.go b/ql/src/experimental/CWE-326/InsufficientKeySizeGood.go new file mode 100644 index 00000000000..b64053c57d5 --- /dev/null +++ b/ql/src/experimental/CWE-326/InsufficientKeySizeGood.go @@ -0,0 +1,16 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" + "fmt" +) + +func main() { + //Generate Private Key + pvk, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + fmt.Println(err) + } + fmt.Println(pvk) +} diff --git a/ql/test/experimental/CWE-326/InsufficientKeySize.expected b/ql/test/experimental/CWE-326/InsufficientKeySize.expected new file mode 100644 index 00000000000..c7840f6adb5 --- /dev/null +++ b/ql/test/experimental/CWE-326/InsufficientKeySize.expected @@ -0,0 +1,15 @@ +edges +| InsufficientKeySize.go:13:10:13:13 | 1024 : int | InsufficientKeySize.go:14:31:14:34 | size | +| InsufficientKeySize.go:18:7:18:10 | 1024 : int | InsufficientKeySize.go:25:11:25:14 | definition of size : int | +| InsufficientKeySize.go:25:11:25:14 | definition of size : int | InsufficientKeySize.go:26:31:26:34 | size | +nodes +| InsufficientKeySize.go:9:31:9:34 | 1024 | semmle.label | 1024 | +| InsufficientKeySize.go:13:10:13:13 | 1024 : int | semmle.label | 1024 : int | +| InsufficientKeySize.go:14:31:14:34 | size | semmle.label | size | +| InsufficientKeySize.go:18:7:18:10 | 1024 : int | semmle.label | 1024 : int | +| InsufficientKeySize.go:25:11:25:14 | definition of size : int | semmle.label | definition of size : int | +| InsufficientKeySize.go:26:31:26:34 | size | semmle.label | size | +#select +| InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:14:31:14:34 | size | InsufficientKeySize.go:13:10:13:13 | 1024 : int | InsufficientKeySize.go:14:31:14:34 | size | The size of this RSA key should be at least 2048 bits. | +| InsufficientKeySize.go:26:31:26:34 | size | InsufficientKeySize.go:18:7:18:10 | 1024 : int | InsufficientKeySize.go:26:31:26:34 | size | The size of this RSA key should be at least 2048 bits. | diff --git a/ql/test/experimental/CWE-326/InsufficientKeySize.go b/ql/test/experimental/CWE-326/InsufficientKeySize.go new file mode 100644 index 00000000000..ad1f1c8de75 --- /dev/null +++ b/ql/test/experimental/CWE-326/InsufficientKeySize.go @@ -0,0 +1,27 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" +) + +func foo1() { + rsa.GenerateKey(rand.Reader, 1024) // BAD +} + +func foo2() { + size := 1024 + rsa.GenerateKey(rand.Reader, size) // BAD +} + +func foo3() { + foo5(1024) // BAD +} + +func foo4() { + foo5(2048) // GOOD +} + +func foo5(size int) { + rsa.GenerateKey(rand.Reader, size) +} diff --git a/ql/test/experimental/CWE-326/InsufficientKeySize.qlref b/ql/test/experimental/CWE-326/InsufficientKeySize.qlref new file mode 100644 index 00000000000..0eb444e257a --- /dev/null +++ b/ql/test/experimental/CWE-326/InsufficientKeySize.qlref @@ -0,0 +1 @@ +experimental/CWE-326/InsufficientKeySize.ql