diff --git a/ql/src/experimental/CWE-327/InsecureTLS.go b/ql/src/experimental/CWE-327/InsecureTLS.go new file mode 100644 index 00000000000..41235c8b4ee --- /dev/null +++ b/ql/src/experimental/CWE-327/InsecureTLS.go @@ -0,0 +1,31 @@ +package main + +import ( + "crypto/tls" +) + +func main() {} + +func insecureMinMaxTlsVersion() { + { + config := &tls.Config{} + config.MinVersion = 0 // BAD: Setting the MinVersion to 0 equals to choosing the lowest supported version (i.e. SSL3.0) + } + { + config := &tls.Config{} + config.MinVersion = tls.VersionSSL30 // BAD: SSL 3.0 is a non-secure version of the protocol; it's not safe to use it as MinVersion. + } + { + config := &tls.Config{} + config.MaxVersion = tls.VersionSSL30 // BAD: SSL 3.0 is a non-secure version of the protocol; it's not safe to use it as MaxVersion. + } +} + +func insecureCipherSuites() { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, // BAD: TLS_RSA_WITH_RC4_128_SHA is one of the non-secure cipher suites; it's not safe to be used. + }, + } + _ = config +} diff --git a/ql/src/experimental/CWE-327/InsecureTLS.qhelp b/ql/src/experimental/CWE-327/InsecureTLS.qhelp new file mode 100644 index 00000000000..7df7c9f8a2a --- /dev/null +++ b/ql/src/experimental/CWE-327/InsecureTLS.qhelp @@ -0,0 +1,47 @@ + + + +

+ The TLS (Transport Layer Security) protocol secures communications over the Internet. + The protocol allows client/server applications to communicate in a way that is designed + to prevent eavesdropping, tampering, or message forgery. +

+

+ The current latest version is 1.3 (with the 1.2 version still being considered secure). + Older versions are not deemed to be secure anymore because of various security vulnerabilities, + and tht makes them unfit for use in securing your applications. +

+

+ Unfortunately, many applications and websites still support deprecated SSL/TLS versions and + cipher suites. +

+
+ +

+ Only use secure TLS versions (1.3 and 1.2) and avoid using insecure cipher suites + (you can see a list here: https://golang.org/src/crypto/tls/cipher_suites.go#L81) +

+
+ +

+ The following example shows a few ways how an insecure TLS configuration can be created: +

+ +

+ The following example shows how to create a safer TLS configuration: +

+ +
+ +
  • + Wikipedia: + Transport Layer Security +
  • +
  • + OWASP: + Transport Layer Protection Cheat Sheet +
  • +
    +
    diff --git a/ql/src/experimental/CWE-327/InsecureTLS.ql b/ql/src/experimental/CWE-327/InsecureTLS.ql new file mode 100644 index 00000000000..e56c1495106 --- /dev/null +++ b/ql/src/experimental/CWE-327/InsecureTLS.ql @@ -0,0 +1,157 @@ +/** + * @name Insecure TLS configuration + * @description If an application supports insecure TLS versions or ciphers, it may be vulnerable to + * man-in-the-middle and other attacks. + * @kind path-problem + * @problem.severity warning + * @id go/insecure-tls + * @tags security + * external/cwe/cwe-327 + */ + +import go +import DataFlow::PathGraph + +/** + * Check whether the file where the node is located is a test file. + */ +predicate isTestFile(DataFlow::Node node) { + // Exclude results in test files: + exists(File file | file = node.getRoot().getFile() | + file instanceof TestFile or file.getPackageName() = "tests" + ) +} + +predicate unsafeTlsVersion(int val, string name) { + // tls.VersionSSL30 + val = 768 and name = "VersionSSL30" + or + // tls.VersionTLS10 + val = 769 and name = "VersionTLS10" + or + // tls.VersionTLS11 + val = 770 and name = "VersionTLS11" + or + // Zero indicates the lowest available version setting for MinVersion, + // or the highest available version setting for MaxVersion. + val = 0 and name = "" +} + +/** + * Flow of unsecure TLS versions into a `tls.Config` struct, + * to the `MinVersion` and `MaxVersion` fields. + */ +class TlsVersionFlowConfig extends TaintTracking::Configuration { + TlsVersionFlowConfig() { this = "TlsVersionFlowConfig" } + + predicate isSource(DataFlow::Node source, int val) { + val = source.getIntValue() and + unsafeTlsVersion(val, _) + } + + predicate isSink(DataFlow::Node sink, Field fld) { + fld.hasQualifiedName("crypto/tls", "Config", ["MinVersion", "MaxVersion"]) and + sink = fld.getAWrite().getRhs() + } + + override predicate isSource(DataFlow::Node source) { isSource(source, _) } + + override predicate isSink(DataFlow::Node sink) { isSink(sink, _) } +} + +/** + * Find insecure TLS versions. + */ +predicate checkTlsVersions(DataFlow::PathNode source, DataFlow::PathNode sink, string message) { + exists(TlsVersionFlowConfig cfg, int version, Field fld | + cfg.hasFlowPath(source, sink) and + cfg.isSource(source.getNode(), version) and + cfg.isSink(sink.getNode(), fld) and + // Exclude tls.Config.Max = 0 (which is OK): + not (version = 0 and fld.getName() = "MaxVersion") + | + version = 0 and + message = "Using lowest TLS version for " + fld + "." + or + version != 0 and + exists(string name | unsafeTlsVersion(version, name) | + message = "Using insecure TLS version " + name + " for " + fld + "." + ) + ) +} + +/** + * Flow of unsecure TLS cipher suites into a `tls.Config` struct, + * to the `CipherSuites` field. + */ +class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration { + TlsInsecureCipherSuitesFlowConfig() { this = "TlsInsecureCipherSuitesFlowConfig" } + + predicate isSourceValueEntity(DataFlow::Node source, string suiteName) { + exists(DataFlow::ValueEntity val | + val.hasQualifiedName("crypto/tls", suiteName) and + ( + suiteName = "TLS_RSA_WITH_RC4_128_SHA" + or + suiteName = "TLS_RSA_WITH_AES_128_CBC_SHA256" + or + suiteName = "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA" + or + suiteName = "TLS_ECDHE_RSA_WITH_RC4_128_SHA" + or + suiteName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" + or + suiteName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" + ) + | + source = val.getARead() + ) + } + + predicate isSourceInsecureCipherSuites(DataFlow::Node source) { + exists(Function insecureCipherSuites | + insecureCipherSuites.hasQualifiedName("crypto/tls", "InsecureCipherSuites") + | + source = insecureCipherSuites.getACall().getResult() + ) + } + + override predicate isSource(DataFlow::Node source) { + // TODO: source can also be result of tls.InsecureCipherSuites()[0].ID + isSourceInsecureCipherSuites(source) + or + isSourceValueEntity(source, _) + } + + override predicate isSink(DataFlow::Node sink) { + exists(DataFlow::Field fld | fld.hasQualifiedName("crypto/tls", "Config", "CipherSuites") | + sink = fld.getAWrite().getRhs() + ) + } +} + +/** + * Find insecure TLS cipher suites. + */ +predicate checkTlsInsecureCipherSuites( + DataFlow::PathNode source, DataFlow::PathNode sink, string message +) { + exists(TlsInsecureCipherSuitesFlowConfig cfg | cfg.hasFlowPath(source, sink) | + exists(string name | cfg.isSourceValueEntity(source.getNode(), name) | + message = "Use of an insecure cipher suite: " + name + "." + ) + or + cfg.isSourceInsecureCipherSuites(source.getNode()) and + message = "Use of an insecure cipher suite from InsecureCipherSuites()." + ) +} + +from DataFlow::PathNode source, DataFlow::PathNode sink, string message +where + ( + checkTlsVersions(source, sink, message) or + checkTlsInsecureCipherSuites(source, sink, message) + ) and + // Exclude results in test code: + not isTestFile(sink.getNode()) +select sink.getNode(), source, sink, message diff --git a/ql/src/experimental/CWE-327/SaferTLS.go b/ql/src/experimental/CWE-327/SaferTLS.go new file mode 100644 index 00000000000..d4cd7ecd17c --- /dev/null +++ b/ql/src/experimental/CWE-327/SaferTLS.go @@ -0,0 +1,11 @@ +package main + +import "crypto/tls" + +func saferTLSConfig() { + config := &tls.Config{} + config.MinVersion = tls.VersionTLS12 + config.MaxVersion = tls.VersionTLS13 + // OR + config.MaxVersion = 0 // GOOD: Setting MaxVersion to 0 means that the highest version available in the package will be used. +} diff --git a/ql/test/experimental/CWE-327/UnsafeTLS.expected b/ql/test/experimental/CWE-327/UnsafeTLS.expected new file mode 100644 index 00000000000..64cf3c6b019 --- /dev/null +++ b/ql/test/experimental/CWE-327/UnsafeTLS.expected @@ -0,0 +1,106 @@ +edges +| UnsafeTLS.go:102:5:102:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | +| UnsafeTLS.go:103:5:103:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | +| UnsafeTLS.go:104:5:104:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | +| UnsafeTLS.go:105:5:105:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | +| UnsafeTLS.go:106:5:106:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | +| UnsafeTLS.go:107:5:107:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | +| UnsafeTLS.go:115:5:115:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:114:18:116:4 | slice literal | +| UnsafeTLS.go:123:5:123:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:122:18:124:4 | slice literal | +| UnsafeTLS.go:131:5:131:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:130:18:132:4 | slice literal | +| UnsafeTLS.go:139:5:139:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:138:18:140:4 | slice literal | +| UnsafeTLS.go:147:5:147:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:146:18:148:4 | slice literal | +| UnsafeTLS.go:155:5:155:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:154:18:156:4 | slice literal | +| UnsafeTLS.go:169:3:169:8 | definition of config [pointer, CipherSuites] | UnsafeTLS.go:170:3:170:8 | config [pointer, CipherSuites] | +| UnsafeTLS.go:169:3:169:8 | definition of config [pointer, CipherSuites] | UnsafeTLS.go:171:3:171:8 | config [pointer, CipherSuites] | +| UnsafeTLS.go:169:3:169:8 | definition of config [pointer, CipherSuites] | UnsafeTLS.go:171:32:171:37 | config [pointer, CipherSuites] | +| UnsafeTLS.go:170:3:170:8 | config [pointer, CipherSuites] | UnsafeTLS.go:170:3:170:8 | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:170:3:170:8 | implicit dereference [CipherSuites] : slice type | UnsafeTLS.go:169:3:169:8 | definition of config [pointer, CipherSuites] | +| UnsafeTLS.go:171:3:171:8 | config [pointer, CipherSuites] | UnsafeTLS.go:171:3:171:8 | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:171:3:171:8 | implicit dereference [CipherSuites] : slice type | UnsafeTLS.go:169:3:169:8 | definition of config [pointer, CipherSuites] | +| UnsafeTLS.go:171:25:171:94 | call to append : slice type | UnsafeTLS.go:171:3:171:8 | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:171:32:171:37 | config [pointer, CipherSuites] | UnsafeTLS.go:171:32:171:37 | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:171:32:171:37 | implicit dereference [CipherSuites] : slice type | UnsafeTLS.go:171:32:171:50 | selection of CipherSuites : slice type | +| UnsafeTLS.go:171:32:171:50 | selection of CipherSuites : slice type | UnsafeTLS.go:171:25:171:94 | call to append | +| UnsafeTLS.go:171:32:171:50 | selection of CipherSuites : slice type | UnsafeTLS.go:171:25:171:94 | call to append : slice type | +| UnsafeTLS.go:171:53:171:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:171:25:171:94 | call to append | +| UnsafeTLS.go:171:53:171:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:171:25:171:94 | call to append : slice type | +| UnsafeTLS.go:193:21:193:46 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:195:40:195:56 | implicit dereference : CipherSuite | +| UnsafeTLS.go:193:21:193:46 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:197:25:197:36 | cipherSuites | +| UnsafeTLS.go:195:40:195:56 | implicit dereference : CipherSuite | UnsafeTLS.go:195:40:195:56 | implicit dereference : CipherSuite | +| UnsafeTLS.go:195:40:195:56 | implicit dereference : CipherSuite | UnsafeTLS.go:197:25:197:36 | cipherSuites | +nodes +| UnsafeTLS.go:12:23:12:23 | 0 | semmle.label | 0 | +| UnsafeTLS.go:16:23:16:23 | 0 | semmle.label | 0 | +| UnsafeTLS.go:21:16:21:16 | 0 | semmle.label | 0 | +| UnsafeTLS.go:27:16:27:16 | 0 | semmle.label | 0 | +| UnsafeTLS.go:34:23:34:38 | selection of VersionSSL30 | semmle.label | selection of VersionSSL30 | +| UnsafeTLS.go:38:23:38:38 | selection of VersionSSL30 | semmle.label | selection of VersionSSL30 | +| UnsafeTLS.go:43:23:43:38 | selection of VersionTLS10 | semmle.label | selection of VersionTLS10 | +| UnsafeTLS.go:47:23:47:38 | selection of VersionTLS10 | semmle.label | selection of VersionTLS10 | +| UnsafeTLS.go:52:23:52:38 | selection of VersionTLS11 | semmle.label | selection of VersionTLS11 | +| UnsafeTLS.go:56:23:56:38 | selection of VersionTLS11 | semmle.label | selection of VersionTLS11 | +| UnsafeTLS.go:61:16:61:31 | selection of VersionTLS11 | semmle.label | selection of VersionTLS11 | +| UnsafeTLS.go:67:16:67:31 | selection of VersionTLS11 | semmle.label | selection of VersionTLS11 | +| UnsafeTLS.go:86:16:86:21 | 0x0300 | semmle.label | 0x0300 | +| UnsafeTLS.go:92:16:92:21 | 0x0301 | semmle.label | 0x0301 | +| UnsafeTLS.go:101:18:108:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:102:5:102:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:103:5:103:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:104:5:104:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:105:5:105:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:106:5:106:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:107:5:107:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:114:18:116:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:115:5:115:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:122:18:124:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:123:5:123:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:130:18:132:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:131:5:131:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:138:18:140:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:139:5:139:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | +| UnsafeTLS.go:146:18:148:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:147:5:147:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:154:18:156:4 | slice literal | semmle.label | slice literal | +| UnsafeTLS.go:155:5:155:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:169:3:169:8 | definition of config [pointer, CipherSuites] | semmle.label | definition of config [pointer, CipherSuites] | +| UnsafeTLS.go:170:3:170:8 | config [pointer, CipherSuites] | semmle.label | config [pointer, CipherSuites] | +| UnsafeTLS.go:170:3:170:8 | implicit dereference [CipherSuites] : slice type | semmle.label | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:171:3:171:8 | config [pointer, CipherSuites] | semmle.label | config [pointer, CipherSuites] | +| UnsafeTLS.go:171:3:171:8 | implicit dereference [CipherSuites] : slice type | semmle.label | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:171:25:171:94 | call to append | semmle.label | call to append | +| UnsafeTLS.go:171:25:171:94 | call to append : slice type | semmle.label | call to append : slice type | +| UnsafeTLS.go:171:32:171:37 | config [pointer, CipherSuites] | semmle.label | config [pointer, CipherSuites] | +| UnsafeTLS.go:171:32:171:37 | implicit dereference [CipherSuites] : slice type | semmle.label | implicit dereference [CipherSuites] : slice type | +| UnsafeTLS.go:171:32:171:50 | selection of CipherSuites : slice type | semmle.label | selection of CipherSuites : slice type | +| UnsafeTLS.go:171:53:171:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | +| UnsafeTLS.go:193:21:193:46 | call to InsecureCipherSuites : slice type | semmle.label | call to InsecureCipherSuites : slice type | +| UnsafeTLS.go:195:40:195:56 | implicit dereference : CipherSuite | semmle.label | implicit dereference : CipherSuite | +| UnsafeTLS.go:197:25:197:36 | cipherSuites | semmle.label | cipherSuites | +#select +| UnsafeTLS.go:12:23:12:23 | 0 | UnsafeTLS.go:12:23:12:23 | 0 | UnsafeTLS.go:12:23:12:23 | 0 | Using lowest TLS version for MinVersion. | +| UnsafeTLS.go:21:16:21:16 | 0 | UnsafeTLS.go:21:16:21:16 | 0 | UnsafeTLS.go:21:16:21:16 | 0 | Using lowest TLS version for MinVersion. | +| UnsafeTLS.go:34:23:34:38 | selection of VersionSSL30 | UnsafeTLS.go:34:23:34:38 | selection of VersionSSL30 | UnsafeTLS.go:34:23:34:38 | selection of VersionSSL30 | Using insecure TLS version VersionSSL30 for MinVersion. | +| UnsafeTLS.go:38:23:38:38 | selection of VersionSSL30 | UnsafeTLS.go:38:23:38:38 | selection of VersionSSL30 | UnsafeTLS.go:38:23:38:38 | selection of VersionSSL30 | Using insecure TLS version VersionSSL30 for MaxVersion. | +| UnsafeTLS.go:43:23:43:38 | selection of VersionTLS10 | UnsafeTLS.go:43:23:43:38 | selection of VersionTLS10 | UnsafeTLS.go:43:23:43:38 | selection of VersionTLS10 | Using insecure TLS version VersionTLS10 for MinVersion. | +| UnsafeTLS.go:47:23:47:38 | selection of VersionTLS10 | UnsafeTLS.go:47:23:47:38 | selection of VersionTLS10 | UnsafeTLS.go:47:23:47:38 | selection of VersionTLS10 | Using insecure TLS version VersionTLS10 for MaxVersion. | +| UnsafeTLS.go:52:23:52:38 | selection of VersionTLS11 | UnsafeTLS.go:52:23:52:38 | selection of VersionTLS11 | UnsafeTLS.go:52:23:52:38 | selection of VersionTLS11 | Using insecure TLS version VersionTLS11 for MinVersion. | +| UnsafeTLS.go:56:23:56:38 | selection of VersionTLS11 | UnsafeTLS.go:56:23:56:38 | selection of VersionTLS11 | UnsafeTLS.go:56:23:56:38 | selection of VersionTLS11 | Using insecure TLS version VersionTLS11 for MaxVersion. | +| UnsafeTLS.go:61:16:61:31 | selection of VersionTLS11 | UnsafeTLS.go:61:16:61:31 | selection of VersionTLS11 | UnsafeTLS.go:61:16:61:31 | selection of VersionTLS11 | Using insecure TLS version VersionTLS11 for MinVersion. | +| UnsafeTLS.go:67:16:67:31 | selection of VersionTLS11 | UnsafeTLS.go:67:16:67:31 | selection of VersionTLS11 | UnsafeTLS.go:67:16:67:31 | selection of VersionTLS11 | Using insecure TLS version VersionTLS11 for MaxVersion. | +| UnsafeTLS.go:86:16:86:21 | 0x0300 | UnsafeTLS.go:86:16:86:21 | 0x0300 | UnsafeTLS.go:86:16:86:21 | 0x0300 | Using insecure TLS version VersionSSL30 for MinVersion. | +| UnsafeTLS.go:92:16:92:21 | 0x0301 | UnsafeTLS.go:92:16:92:21 | 0x0301 | UnsafeTLS.go:92:16:92:21 | 0x0301 | Using insecure TLS version VersionTLS10 for MaxVersion. | +| UnsafeTLS.go:101:18:108:4 | slice literal | UnsafeTLS.go:102:5:102:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:101:18:108:4 | slice literal | UnsafeTLS.go:103:5:103:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:101:18:108:4 | slice literal | UnsafeTLS.go:104:5:104:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:101:18:108:4 | slice literal | UnsafeTLS.go:105:5:105:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:101:18:108:4 | slice literal | UnsafeTLS.go:106:5:106:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:101:18:108:4 | slice literal | UnsafeTLS.go:107:5:107:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:101:18:108:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:114:18:116:4 | slice literal | UnsafeTLS.go:115:5:115:32 | selection of TLS_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:114:18:116:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:122:18:124:4 | slice literal | UnsafeTLS.go:123:5:123:39 | selection of TLS_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:122:18:124:4 | slice literal | Use of an insecure cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:130:18:132:4 | slice literal | UnsafeTLS.go:131:5:131:40 | selection of TLS_ECDHE_ECDSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:130:18:132:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:138:18:140:4 | slice literal | UnsafeTLS.go:139:5:139:38 | selection of TLS_ECDHE_RSA_WITH_RC4_128_SHA : uint16 | UnsafeTLS.go:138:18:140:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA. | +| UnsafeTLS.go:146:18:148:4 | slice literal | UnsafeTLS.go:147:5:147:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:146:18:148:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:154:18:156:4 | slice literal | UnsafeTLS.go:155:5:155:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:154:18:156:4 | slice literal | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:171:25:171:94 | call to append | UnsafeTLS.go:171:53:171:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : uint16 | UnsafeTLS.go:171:25:171:94 | call to append | Use of an insecure cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256. | +| UnsafeTLS.go:197:25:197:36 | cipherSuites | UnsafeTLS.go:193:21:193:46 | call to InsecureCipherSuites : slice type | UnsafeTLS.go:197:25:197:36 | cipherSuites | Use of an insecure cipher suite from InsecureCipherSuites(). | diff --git a/ql/test/experimental/CWE-327/UnsafeTLS.go b/ql/test/experimental/CWE-327/UnsafeTLS.go new file mode 100644 index 00000000000..accbf04fa26 --- /dev/null +++ b/ql/test/experimental/CWE-327/UnsafeTLS.go @@ -0,0 +1,199 @@ +package main + +import ( + "crypto/tls" +) + +func main() {} + +func minMaxTlsVersion() { + { + config := &tls.Config{} + config.MinVersion = 0 // BAD + } + { + config := &tls.Config{} + config.MaxVersion = 0 // GOOD + } + /// + { + config := &tls.Config{ + MinVersion: 0, // BAD + } + _ = config + } + { + config := &tls.Config{ + MaxVersion: 0, // GOOD + } + _ = config + } + /// + { + config := &tls.Config{} + config.MinVersion = tls.VersionSSL30 // BAD + } + { + config := &tls.Config{} + config.MaxVersion = tls.VersionSSL30 // BAD + } + /// + { + config := &tls.Config{} + config.MinVersion = tls.VersionTLS10 // BAD + } + { + config := &tls.Config{} + config.MaxVersion = tls.VersionTLS10 // BAD + } + /// + { + config := &tls.Config{} + config.MinVersion = tls.VersionTLS11 // BAD + } + { + config := &tls.Config{} + config.MaxVersion = tls.VersionTLS11 // BAD + } + /// + { + config := &tls.Config{ + MinVersion: tls.VersionTLS11, // BAD + } + _ = config + } + { + config := &tls.Config{ + MaxVersion: tls.VersionTLS11, // BAD + } + _ = config + } + { + config := &tls.Config{ + MinVersion: tls.VersionTLS12, // GOOD + } + _ = config + } + { + config := &tls.Config{ + MaxVersion: tls.VersionTLS13, // GOOD + } + _ = config + } + /// + { + config := &tls.Config{ + MinVersion: 0x0300, // BAD + } + _ = config + } + { + config := &tls.Config{ + MaxVersion: 0x0301, // BAD + } + _ = config + } +} + +func cipherSuites() { + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, // BAD + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // BAD + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // BAD + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, // BAD + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // BAD + }, + } + _ = config + } + { + config := &tls.Config{ + CipherSuites: []uint16{ + tls.TLS_CHACHA20_POLY1305_SHA256, // GOOD + }, + } + _ = config + } + { + config := &tls.Config{} + config.CipherSuites = make([]uint16, 0) + config.CipherSuites = append(config.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) // BAD + } + { + config := &tls.Config{} + config.CipherSuites = make([]uint16, 0) + insecureSuites := tls.InsecureCipherSuites() + for _, v := range insecureSuites { + config.CipherSuites = append(config.CipherSuites, v.ID) // TODO: should be flagged as BAD. + } + } + { + config := &tls.Config{} + cipherSuites := make([]uint16, 0) + insecureSuites := tls.InsecureCipherSuites() + for _, v := range insecureSuites { + cipherSuites = append(cipherSuites, v.ID) + } + config.CipherSuites = cipherSuites // TODO: should be flagged as BAD. + } + { + config := &tls.Config{} + cipherSuites := make([]uint16, 0) + insecureSuites := tls.InsecureCipherSuites() + for i := range insecureSuites { + cipherSuites = append(cipherSuites, insecureSuites[i].ID) + } + config.CipherSuites = cipherSuites // BAD + } +} diff --git a/ql/test/experimental/CWE-327/UnsafeTLS.qlref b/ql/test/experimental/CWE-327/UnsafeTLS.qlref new file mode 100644 index 00000000000..9b614dde9fa --- /dev/null +++ b/ql/test/experimental/CWE-327/UnsafeTLS.qlref @@ -0,0 +1 @@ +experimental/CWE-327/InsecureTLS.ql