problem-based-packs.insecure-transport.go-stdlib.disallow-old-tls-versions.disallow-old-tls-versions

profile photo of semgrepsemgrep
Author
6,272
Download Count*

Detects creations of tls configuration objects with an insecure MinVersion of TLS. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities.

Run Locally

Run in CI

Defintion

rules:
  - id: disallow-old-tls-versions
    message: Detects creations of tls configuration objects with an insecure
      MinVersion of TLS. These protocols are deprecated due to POODLE, man in
      the middle attacks, and other vulnerabilities.
    severity: WARNING
    metadata:
      likelihood: HIGH
      impact: MEDIUM
      confidence: HIGH
      category: security
      cwe: "CWE-319: Cleartext Transmission of Sensitive Information"
      owasp: A03:2017 - Sensitive Data Exposure
      references:
        - https://stackoverflow.com/questions/26429751/java-http-clients-and-poodle
      subcategory:
        - vuln
      technology:
        - go
      vulnerability: Insecure Transport
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mishandled Sensitive Information
    languages:
      - go
    patterns:
      - pattern-either:
          - pattern: |
              tls.Config{..., MinVersion: $TLS.$VERSION, ...}
          - pattern: |
              $CONFIG = &tls.Config{...}
              ...
              $CONFIG.MinVersion = $TLS.$VERSION
      - metavariable-regex:
          metavariable: $VERSION
          regex: (VersionTLS10|VersionTLS11|VersionSSL30)

Examples

disallow-old-tls-versions.go

package main

import (
	"crypto/tls"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
)

func ok1() {
	// 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) {}))
	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: disallow-old-tls-versions
			TLSClientConfig: &tls.Config{
				KeyLogWriter:       w,
				MinVersion:         tls.VersionTLS12,
				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()


	client_good := &http.Client{
		Transport: &http.Transport{
            // ok: disallow-old-tls-versions
			TLSClientConfig: &tls.Config{
				KeyLogWriter: w,
				MinVersion:         tls.VersionTLS13,
				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()
}

func ok2() {
    // ok: disallow-old-tls-versions
    mTLSConfig := &tls.Config {
    }

    mTLSConfig.PreferServerCipherSuites = true
    mTLSConfig.MinVersion = tls.VersionTLS13
}

func bad1() {
	// 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) {}))
	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{
            // ruleid: disallow-old-tls-versions
			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()


	client_good := &http.Client{
		Transport: &http.Transport{
            // ruleid: disallow-old-tls-versions
			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()
}

func bad2() {
    // ruleid: disallow-old-tls-versions
    mTLSConfig := &tls.Config {
    }

    mTLSConfig.PreferServerCipherSuites = true
    mTLSConfig.MinVersion = tls.VersionTLS11
}