Improper Request Certificate Verification

ID

python.request_without_certificate_verification

Severity

high

Resource

Misconfiguration

Language

Python

Tags

CWE:295, NIST.SP.800-53, OWASP:2021:A2, OWASP:2021:A7, PCI-DSS:6.5.4

Description

Disabling SSL/TLS certificate verification allows attackers to intercept and manipulate data in transit between the client and server, compromising security by facilitating man-in-the-middle attacks.

Rationale

Certificates are used to establish secure HTTPS connections by ensuring that the server is who it claims to be. If these certificates are not verified, it opens the connection to risks such as data interception and manipulation.

In Python, using libraries like requests without proper certificate verification can lead to these vulnerabilities. Here’s an example demonstrating this issue:

import requests

def fetch_data():
    # Insecure request without certificate verification
    response = requests.get('https://example.com/data', verify=False) # FLAW
    return response.content

In this example, verify=False is used, which disables SSL certificate verification. This means the server’s identity is not authenticated, allowing potential man-in-the-middle attacks.

Remediation

To ensure secure communication, always verify certificates by default and utilize trusted Certificate Authorities (CAs). Here’s how you can enforce certificate verification:

import requests

def fetch_data():
    # Secure request with certificate verification
    response = requests.get('https://example.com/data', verify=True)
    return response.content

By omitting verify=False or explicitly setting verify=True, you ensure that the server’s SSL certificate is checked against a list of trusted CAs. For cases where you use self-signed certificates, you can specify the path to a trusted certificate file:

import requests

def fetch_data():
    # Secure request with custom CA bundle for self-signed certificates
    response = requests.get('https://example.com/data', verify='/path/to/cert.pem')
    return response.content

Using verify='/path/to/cert.pem' ensures that even custom certificates are validated properly, maintaining the secure integrity of the HTTPS connection.

References