go.lang.security.audit.crypto.missing-ssl-minversion.missing-ssl-minversion
Community Favorite

Author
11,300
Download Count*
License
MinVersion
is missing from this TLS configuration. The default value is TLS1.0 which is considered insecure. Explicitly set the MinVersion
to a secure version of TLS, such as VersionTLS13
.
Run Locally
Run in CI
Defintion
rules:
- id: missing-ssl-minversion
message: "`MinVersion` is missing from this TLS configuration. The default value
is TLS1.0 which is considered insecure. Explicitly set the `MinVersion` to
a secure version of TLS, such as `VersionTLS13`."
metadata:
cwe:
- "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
owasp:
- A03:2017 - Sensitive Data Exposure
- A02:2021 - Cryptographic Failures
source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go
references:
- https://golang.org/doc/go1.14#crypto/tls
- https://golang.org/pkg/crypto/tls/#:~:text=MinVersion
- https://www.us-cert.gov/ncas/alerts/TA14-290A
category: security
technology:
- go
confidence: HIGH
subcategory:
- audit
likelihood: MEDIUM
impact: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- go
severity: WARNING
patterns:
- pattern: tls.Config{...}
- pattern-not-inside: "tls.Config{..., MinVersion: ..., ...}"
fix-regex:
regex: Config\s*\{
replacement: "Config{MinVersion: SSL.VersionTLS13,"
Examples
missing-ssl-minversion.go
package main
import (
"crypto/tls"
"log"
"net/http"
"net/http/httptest"
"os"
)
// zeroSource is an io.Reader that returns an unlimited number of zero bytes.
type zeroSource struct{}
func (zeroSource) Read(b []byte) (n int, err error) {
for i := range b {
b[i] = 0
}
return len(b), nil
}
func main() {
// Dummy test HTTP server for the example with insecure random so output is
// reproducible.
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
// ruleid: missing-ssl-minversion
server.TLS = &tls.Config{
Rand: zeroSource{}, // for example only; don't do this.
}
server.StartTLS()
defer server.Close()
// Typically the log would go to an open file:
// w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
w := os.Stdout
client := &http.Client{
Transport: &http.Transport{
// ok: missing-ssl-minversion
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.
},
},
}
resp, err := client.Get(server.URL)
if err != nil {
log.Fatalf("Failed to get URL: %v", err)
}
resp.Body.Close()
clientGood := &http.Client{
Transport: &http.Transport{
// ok: missing-ssl-minversion
TLSClientConfig: &tls.Config{
KeyLogWriter: w,
MinVersion: tls.VersionTLS10,
Rand: zeroSource{}, // for reproducible output; don't do this.
InsecureSkipVerify: true, // test server certificate is not trusted.
},
},
}
resp, err := client.Get(server.URL)
if err != nil {
log.Fatalf("Failed to get URL: %v", err)
}
resp.Body.Close()
}
Short Link: https://sg.run/oxEN