Skip to content

VNX-GO-004: TLS InsecureSkipVerify enabled

Reports InsecureSkipVerify set to the constant true in a tls.Config literal or assignment. A value from a variable, flag or environment, true inside an if on the insecure option itself, a config with its own VerifyPeerCertificate/VerifyConnection, comments, strings and test code (including test-support packages such as httptest and testutil) are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-GO-004
Severity High
SARIF level error
Kind sast
Languages Go
CWE CWE-295
CAPEC CAPEC-94
ATT&CK T1557
CWSS vector CWSS:1.0/TI:H/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H
Tags tls certificate mitm transport-security
Source internal/sast/rules/vnx-go-004.rego

Overview

This rule flags any Go source file that sets InsecureSkipVerify: true inside a tls.Config struct. When this flag is enabled the TLS stack accepts any certificate, expired, self-signed, issued by an untrusted authority, or one belonging to a completely different host, without complaint. This removes the authentication guarantee that TLS is designed to provide and makes every HTTPS connection your application initiates trivially interceptable. The vulnerability maps to CWE-295: Improper Certificate Validation.

Go idiom note: Full TLS certificate validation IS the Go default. A default http.Client{} or tls.Config{} with no fields set performs complete chain and hostname verification against the system trust store. Setting InsecureSkipVerify: true is an explicit, non-default override that must be actively written, the secure behavior requires no code at all.

Why This Matters

TLS serves two purposes: encrypting traffic in transit and authenticating the remote endpoint. InsecureSkipVerify disables the second. An attacker on the same network, a shared Wi-Fi, a cloud VPC, a compromised router, can present a fake certificate and intercept all traffic your application sends or receives. This is a man-in-the-middle attack (MITRE ATT&CK T1557). In practice this means API keys, session tokens, database credentials, and user data transmitted over what appears to be a secure HTTPS connection are fully visible to the attacker. The pattern commonly appears when developers work around certificate issues during development and the flag accidentally ships to production.

OWASP ASVS v4.0 requirement V9.1.2 requires that TLS certificates be valid, not expired, not revoked, and that the hostname matches. Requirement V9.1.3 requires that only strong cipher suites are used. InsecureSkipVerify violates V9.1.2 entirely by design.

What Gets Flagged

The rule fires on InsecureSkipVerify: true in a struct literal and on x.InsecureSkipVerify = true, in production Go code. A debug switch (if debug {) does not make it safe. It does not fire when the value comes from a variable, flag or environment value (the operator’s choice), when true is set inside an if whose condition names the insecure option (if o.Insecure {, like curl -k), when the same config installs its own VerifyPeerCertificate or VerifyConnection callback (certificate pinning), in _test.go/testdata code, or in comments and strings.

// FLAGGED: certificate validation completely disabled
tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://internal-api.example.com/data")
// FLAGGED: also matches assignment form
cfg := &tls.Config{}
cfg.InsecureSkipVerify = true

Remediation

  1. Remove InsecureSkipVerify: true entirely. The Go TLS stack validates certificates correctly by default. Simply removing the field (or setting it to false) restores full certificate verification with no other changes required.
// SAFE: default TLS configuration with certificate validation enabled
client := &http.Client{}
resp, err := client.Get("https://internal-api.example.com/data")
  1. Trust additional Certificate Authorities without disabling verification. If you need to trust a private CA (e.g., an internal PKI for service-to-service communication), load its certificate into a custom tls.Config rather than disabling verification:
// SAFE: trust a private CA while keeping certificate validation intact
import (
    "crypto/tls"
    "crypto/x509"
    "os"
)

func tlsConfigWithPrivateCA(caPath string) (*tls.Config, error) {
    caCert, err := os.ReadFile(caPath)
    if err != nil {
        return nil, err
    }
    pool := x509.NewCertPool()
    if !pool.AppendCertsFromPEM(caCert) {
        return nil, fmt.Errorf("failed to parse CA certificate")
    }
    return &tls.Config{RootCAs: pool}, nil
}
  1. Use InsecureSkipVerify only in isolated test environments with a test-only build tag. If you absolutely need to skip verification in a local integration test, gate it behind a build tag so it can never reach production code.
//go:build integration_test

package mypackage

import "crypto/tls"

func testTLSConfig() *tls.Config {
    return &tls.Config{InsecureSkipVerify: true} // test-only, never in production
}
  1. Fix the underlying certificate issue. If InsecureSkipVerify was added to work around a certificate error, fix the root cause: renew expired certificates, install the correct CA bundle, or configure the server with a valid certificate from a trusted CA.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-go-004
// nosec vnx-go-004

Or record an ignore rule: vulnetix ignore add --rule vnx-go-004 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-go-004.rego, cli/internal/sast/docs/vnx-go-004.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.