Insecure TLS via danger_accept_invalid_certs in Rust reqwest

High Risk Network Security
rustreqwesttlscertificate-validationmitmhttps

What it is

TLS certificate validation bypass vulnerabilities occur when reqwest HTTP clients use danger_accept_invalid_certs(true) or danger_accept_invalid_hostnames(true). This disables critical security checks, allowing man-in-the-middle attackers to intercept HTTPS traffic by presenting invalid, self-signed, or mismatched certificates, exposing credentials, API keys, and sensitive data.

use reqwest::{Client, ClientBuilder};

// VULNERABLE: accepts invalid certificates and hostnames
pub fn create_insecure_client() -> Result<Client, reqwest::Error> {
    ClientBuilder::new()
        // DANGEROUS: bypasses certificate validation
        .danger_accept_invalid_certs(true)
        // DANGEROUS: bypasses hostname verification
        .danger_accept_invalid_hostnames(true)
        .build()
}

pub async fn fetch_sensitive_data(client: &Client, api_key: &str) 
    -> Result<String, reqwest::Error> {
    // Credentials sent over potentially compromised connection
    let response = client
        .get("https://api.example.com/user/data")
        .header("Authorization", format!("Bearer {}", api_key))
        .send()
        .await?;
    
    response.text().await
}
use reqwest::{Client, ClientBuilder, Certificate};
use std::fs;

// SECURE: uses default certificate validation
pub fn create_secure_client() -> Result<Client, reqwest::Error> {
    ClientBuilder::new()
        // No danger_accept calls - uses secure defaults
        .timeout(std::time::Duration::from_secs(30))
        .build()
}

// For custom CA certificates
pub fn create_client_with_custom_ca(ca_cert_path: &str) 
    -> Result<Client, reqwest::Error> {
    // Load custom CA certificate
    let ca_cert_pem = fs::read(ca_cert_path)
        .expect("Failed to read CA certificate");
    let ca_cert = Certificate::from_pem(&ca_cert_pem)?;
    
    ClientBuilder::new()
        .add_root_certificate(ca_cert)
        .timeout(std::time::Duration::from_secs(30))
        .build()
}

pub async fn fetch_sensitive_data(client: &Client, api_key: &str) 
    -> Result<String, reqwest::Error> {
    // Credentials sent over validated TLS connection
    let response = client
        .get("https://api.example.com/user/data")
        .header("Authorization", format!("Bearer {}", api_key))
        .send()
        .await?;
    
    response.text().await
}

💡 Why This Fix Works

The vulnerable code disables certificate and hostname validation, allowing attackers to present invalid certificates and intercept HTTPS traffic. The secure version uses default certificate validation, and shows how to add custom CA certificates when needed without disabling security.

Why it happens

Disabling certificate validation to bypass certificate errors.

Root causes

Using danger_accept_invalid_certs(true)

Disabling certificate validation to bypass certificate errors.

Using danger_accept_invalid_hostnames(true)

Disabling hostname verification to connect to servers with mismatched certificates.

Testing Configurations in Production

Leaving insecure testing configurations enabled in production code.

Fixes

1

Remove Certificate Bypass Flags

Remove danger_accept_invalid_certs() and danger_accept_invalid_hostnames() calls.

2

Use add_root_certificate()

For self-signed certificates, add specific CA certificates using add_root_certificate().

3

Implement Certificate Pinning

For critical applications, validate certificate fingerprints to prevent MITM attacks.

Detect This Vulnerability in Your Code

Sourcery automatically identifies insecure tls via danger_accept_invalid_certs in rust reqwest and many other security issues in your codebase.