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

Community Favorite
profile photo of semgrepsemgrep
Author
11,300
Download Count*

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.

Run Locally

Run in CI

Defintion

rules:
  - id: missing-ssl-minversion
    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."
    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:
        - guardrail
      likelihood: MEDIUM
      impact: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cryptographic Issues
    languages:
      - go
    severity: WARNING
    patterns:
      - pattern: |
          tls.Config{ $...CONF }
      - pattern-not: |
          tls.Config{..., MinVersion: ..., ...}
    fix: |
      tls.Config{ $...CONF, MinVersion: tls.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()
}