diff --git a/rules/go/security/missing-ssl-minversion-go.yml b/rules/go/security/missing-ssl-minversion-go.yml new file mode 100644 index 00000000..038d44b5 --- /dev/null +++ b/rules/go/security/missing-ssl-minversion-go.yml @@ -0,0 +1,50 @@ +id: missing-ssl-minversion-go +language: go +severity: warning +message: >- + MinVersion` is missing from this TLS configuration. By default, TLS + 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 + when acting as a server. General purpose web applications should default + to TLS 1.3 with all other protocols disabled. Only where it is known that + a web server must support legacy clients with unsupported an insecure + browsers (such as Internet Explorer 10), it may be necessary to enable TLS + 1.0 to provide support. Add `MinVersion: tls.VersionTLS13' to the TLS + configuration to bump the minimum version to TLS 1.3. +note: >- + [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm + [OWASP A03:2017]: Sensitive Data Exposure + [OWASP A02:2021]: Cryptographic Failures + [REFERENCES] + https://owasp.org/Top10/A02_2021-Cryptographic_Failures + +ast-grep-essentials: true + +utils: + match_tls_without_minversion: + kind: composite_literal + all: + - has: + kind: qualified_type + all: + - has: + kind: package_identifier + regex: "^tls$" + - has: + kind: type_identifier + field: name + regex: "^Config$" + - has: + kind: literal_value + not: + has: + kind: keyed_element + all: + - has: + kind: literal_element + regex: ^MinVersion$ + - has: + pattern: $A +rule: + any: + - matches: match_tls_without_minversion + diff --git a/rules/go/security/ssl-v3-is-insecure-go.yml b/rules/go/security/ssl-v3-is-insecure-go.yml new file mode 100644 index 00000000..c57f00dd --- /dev/null +++ b/rules/go/security/ssl-v3-is-insecure-go.yml @@ -0,0 +1,47 @@ +id: ssl-v3-is-insecure-go +language: go +severity: warning +message: >- + SSLv3 is insecure because it has known vulnerabilities. Starting with + go1.14, SSLv3 will be removed. Instead, use 'tls.VersionTLS13'. +note: >- + [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm + [OWASP A03:2017]: Sensitive Data Exposure + [OWASP A02:2021]: Cryptographic Failures + [REFERENCES] + https://golang.org/doc/go1.14#crypto/tls + https://www.us-cert.gov/ncas/alerts/TA14-290A + +ast-grep-essentials: true + +utils: + match_version: + kind: composite_literal + all: + - has: + kind: qualified_type + regex: ^(tls.Config)$ + - has: + kind: literal_value + has: + kind: keyed_element + all: + - has: + kind: literal_element + regex: "^MinVersion$" + - has: + kind: literal_element + has: + kind: selector_expression + all: + - has: + kind: identifier + - has: + kind: field_identifier + regex: "^VersionSSL30$" + +rule: + any: + - matches: match_version + + diff --git a/rules/go/security/tls-with-insecure-cipher-go.yml b/rules/go/security/tls-with-insecure-cipher-go.yml new file mode 100644 index 00000000..bfa88863 --- /dev/null +++ b/rules/go/security/tls-with-insecure-cipher-go.yml @@ -0,0 +1,71 @@ +id: tls-with-insecure-cipher-go +language: go +severity: warning +message: >- + Detected an insecure CipherSuite via the 'tls' module. This suite is + considered weak. Use the function 'tls.CipherSuites()' to get a list of + good cipher suites. See + https://golang.org/pkg/crypto/tls/#InsecureCipherSuites for why and what + other cipher suites to use. +note: >- + [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm + [OWASP A03:2017]: Sensitive Data Exposure + [OWASP A02:2021]: Cryptographic Failures + [REFERENCES] + https://owasp.org/Top10/A02_2021-Cryptographic_Failures + +ast-grep-essentials: true + +utils: + match_tls_ciphersuite: + kind: composite_literal + all: + - has: + kind: qualified_type + regex: ^(tls.CipherSuite)$ + - has: + kind: literal_value + has: + kind: literal_element + regex: ^(TLS_RSA_WITH_RC4_128_SHA|TLS_RSA_WITH_3DES_EDE_CBC_SHA|TLS_RSA_WITH_AES_128_CBC_SHA256|TLS_ECDHE_ECDSA_WITH_RC4_128_SHA|TLS_ECDHE_RSA_WITH_RC4_128_SHA|TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256|TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)$ + method_tls_config: + kind: composite_literal + all: + - has: + kind: qualified_type + regex: ^(tls.Config)$ + - has: + stopBy: end + kind: literal_value + has: + stopBy: end + kind: keyed_element + all: + - has: + kind: literal_element + has: + kind: identifier + regex: "^CipherSuites$" + - has: + kind: literal_element + has: + kind: composite_literal + has: + kind: literal_value + has: + kind: literal_element + has: + kind: selector_expression + all: + - has: + kind: identifier + regex: "^tls$" + - has: + kind: field_identifier + regex: ^(TLS_RSA_WITH_RC4_128_SHA|TLS_RSA_WITH_3DES_EDE_CBC_SHA|TLS_RSA_WITH_AES_128_CBC_SHA256|TLS_ECDHE_ECDSA_WITH_RC4_128_SHA|TLS_ECDHE_RSA_WITH_RC4_128_SHA|TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256|TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)$ + +rule: + any: + - matches: match_tls_ciphersuite + - matches: method_tls_config + diff --git a/tests/__snapshots__/missing-ssl-minversion-go-snapshot.yml b/tests/__snapshots__/missing-ssl-minversion-go-snapshot.yml new file mode 100644 index 00000000..3cb06bac --- /dev/null +++ b/tests/__snapshots__/missing-ssl-minversion-go-snapshot.yml @@ -0,0 +1,25 @@ +id: missing-ssl-minversion-go +snapshots: + ? | + server.TLS = &tls.Config{ Rand: zeroSource{}, } + : labels: + - source: 'tls.Config{ Rand: zeroSource{}, }' + style: primary + start: 14 + end: 47 + - source: tls + style: secondary + start: 14 + end: 17 + - source: Config + style: secondary + start: 18 + end: 24 + - source: tls.Config + style: secondary + start: 14 + end: 24 + - source: '{ Rand: zeroSource{}, }' + style: secondary + start: 24 + end: 47 diff --git a/tests/__snapshots__/ssl-v3-is-insecure-go-snapshot.yml b/tests/__snapshots__/ssl-v3-is-insecure-go-snapshot.yml new file mode 100644 index 00000000..b8b92971 --- /dev/null +++ b/tests/__snapshots__/ssl-v3-is-insecure-go-snapshot.yml @@ -0,0 +1,63 @@ +id: ssl-v3-is-insecure-go +snapshots: + ? | + client := &http.Client{ + Transport: &http.Transport{ + // ruleid: ssl-v3-is-insecure + TLSClientConfig: &tls.Config{ + KeyLogWriter: w, + MinVersion: tls.VersionSSL30, + Rand: zeroSource{}, // for reproducible output; don't do this. + InsecureSkipVerify: true, // test server certificate is not trusted. + }, + }, + } + : labels: + - source: |- + tls.Config{ + KeyLogWriter: w, + MinVersion: tls.VersionSSL30, + Rand: zeroSource{}, // for reproducible output; don't do this. + InsecureSkipVerify: true, // test server certificate is not trusted. + } + style: primary + start: 107 + end: 358 + - source: tls.Config + style: secondary + start: 107 + end: 117 + - source: MinVersion + style: secondary + start: 152 + end: 162 + - source: tls + style: secondary + start: 172 + end: 175 + - source: VersionSSL30 + style: secondary + start: 176 + end: 188 + - source: tls.VersionSSL30 + style: secondary + start: 172 + end: 188 + - source: tls.VersionSSL30 + style: secondary + start: 172 + end: 188 + - source: 'MinVersion: tls.VersionSSL30' + style: secondary + start: 152 + end: 188 + - source: |- + { + KeyLogWriter: w, + MinVersion: tls.VersionSSL30, + Rand: zeroSource{}, // for reproducible output; don't do this. + InsecureSkipVerify: true, // test server certificate is not trusted. + } + style: secondary + start: 117 + end: 358 diff --git a/tests/__snapshots__/tls-with-insecure-cipher-go-snapshot.yml b/tests/__snapshots__/tls-with-insecure-cipher-go-snapshot.yml new file mode 100644 index 00000000..25ce56d9 --- /dev/null +++ b/tests/__snapshots__/tls-with-insecure-cipher-go-snapshot.yml @@ -0,0 +1,86 @@ +id: tls-with-insecure-cipher-go +snapshots: + ? | + tr := &http.Transport{ + TLSClientConfig: &tls.Config{CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + }}, + } + : labels: + - source: |- + tls.Config{CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + }} + style: primary + start: 41 + end: 151 + - source: tls.Config + style: secondary + start: 41 + end: 51 + - source: CipherSuites + style: secondary + start: 52 + end: 64 + - source: CipherSuites + style: secondary + start: 52 + end: 64 + - source: tls + style: secondary + start: 78 + end: 81 + - source: TLS_RSA_WITH_RC4_128_SHA + style: secondary + start: 82 + end: 106 + - source: tls.TLS_RSA_WITH_RC4_128_SHA + style: secondary + start: 78 + end: 106 + - source: tls.TLS_RSA_WITH_RC4_128_SHA + style: secondary + start: 78 + end: 106 + - source: |- + { + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + } + style: secondary + start: 74 + end: 150 + - source: |- + []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + } + style: secondary + start: 66 + end: 150 + - source: |- + []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + } + style: secondary + start: 66 + end: 150 + - source: |- + CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + } + style: secondary + start: 52 + end: 150 + - source: |- + {CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + }} + style: secondary + start: 51 + end: 151 diff --git a/tests/go/missing-ssl-minversion-go-test.yml b/tests/go/missing-ssl-minversion-go-test.yml new file mode 100644 index 00000000..55f34ae6 --- /dev/null +++ b/tests/go/missing-ssl-minversion-go-test.yml @@ -0,0 +1,15 @@ +id: missing-ssl-minversion-go +valid: + - | + TLSClientConfig: &tls.Config{ + KeyLogWriter: w, + MinVersion: tls.VersionSSL30, + Rand: zeroSource{}, + InsecureSkipVerify: true, + }, + +invalid: + - | + server.TLS = &tls.Config{ Rand: zeroSource{}, } + + diff --git a/tests/go/ssl-v3-is-insecure-go-test.yml b/tests/go/ssl-v3-is-insecure-go-test.yml new file mode 100644 index 00000000..7294ee90 --- /dev/null +++ b/tests/go/ssl-v3-is-insecure-go-test.yml @@ -0,0 +1,30 @@ +id: ssl-v3-is-insecure-go +valid: + - | + client_good := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + KeyLogWriter: w, + // OK + MinVersion: tls.VersionTLS10, + Rand: zeroSource{}, // for reproducible output; don't do this. + InsecureSkipVerify: true, // test server certificate is not trusted. + }, + }, + } + +invalid: + - | + client := &http.Client{ + Transport: &http.Transport{ + // ruleid: ssl-v3-is-insecure + TLSClientConfig: &tls.Config{ + KeyLogWriter: w, + MinVersion: tls.VersionSSL30, + Rand: zeroSource{}, // for reproducible output; don't do this. + InsecureSkipVerify: true, // test server certificate is not trusted. + }, + }, + } + + diff --git a/tests/go/tls-with-insecure-cipher-go-test.yml b/tests/go/tls-with-insecure-cipher-go-test.yml new file mode 100644 index 00000000..771dc011 --- /dev/null +++ b/tests/go/tls-with-insecure-cipher-go-test.yml @@ -0,0 +1,20 @@ +id: tls-with-insecure-cipher-go +valid: + - | + tr := &http.Transport{ + TLSClientConfig: &tls.Config{CipherSuites: []uint16{ + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_AES_256_GCM_SHA384, + }}, + } + +invalid: + - | + tr := &http.Transport{ + TLSClientConfig: &tls.Config{CipherSuites: []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + }}, + } + +