Security Resources

⌘K
  1. Home
  2. Security Resources
  3. Secure Code Explain
  4. Disabled TLS Certificate Validation

Disabled TLS Certificate Validation

Here is an example of Python code that is vulnerable to disabled TLS certificate validation:

🥺 Vulnerable Code

import requests
import urllib3

urllib3.disable_warnings()   # silence the only warning you would have seen


def fetch_invoice(invoice_id):
    # Vulnerable: certificate and hostname checks switched off to "fix" a TLS error
    return requests.get(
        f"https://billing.internal.example.com/api/invoices/{invoice_id}",
        headers={"Authorization": f"Bearer {API_TOKEN}"},
        verify=False,
        timeout=10,
    ).json()

verify=False turns HTTPS into encryption without authentication. Anyone in a position to intercept the connection - a rogue device on the network, a poisoned DNS record, a compromised sidecar - presents a self-signed certificate, reads the bearer token in the header, and rewrites the invoice data on the way back. Suppressing the warning removes the last chance anyone had of noticing.

😎 Secure Code

Here is a version of the same code that is secured against disabled TLS certificate validation:

import requests

INTERNAL_CA_BUNDLE = "/etc/ssl/certs/internal-root-ca.pem"

session = requests.Session()
session.verify = INTERNAL_CA_BUNDLE                       # trust our CA, not nothing
session.headers["Authorization"] = f"Bearer {load_token_from_vault()}"


def fetch_invoice(invoice_id):
    response = session.get(
        f"https://billing.internal.example.com/api/invoices/{invoice_id}",
        timeout=10,
    )
    response.raise_for_status()
    return response.json()

The usual reason people reach for verify=False is an internal certificate the system trust store does not know about, and the fix is to point verify at that CA bundle instead. For high-value service-to-service calls, add mutual TLS with a client certificate, or pin the expected issuer. Then add a Semgrep or Bandit rule to CI so verify=False, rejectUnauthorized: false, and blanket trust managers never merge again.