How to Avoid Errors with Self-Signed Certificates When Basic Constraints are Not Critical in Python 3.13 with VERIFY_X509_STRICT

Python
2025-05-21 02:50 (9 months ago)
Security's No Joke
Play a song themed on this article

Note: This article discusses intentionally lowering the default security level. Please only proceed if you understand the risks and can tolerate them in your environment.

When attempting to make a request to an HTTP server using a self-signed SSL certificate with Python's Requests or httpx, you would use code similar to the following:

import httpx

ca_file_path = os.path.join(os.path.dirname(__file__), 'my-ca.crt')
content = httpx.get('https://my-internal-server.example.com/', verify=ca_file_path)
import requests

ca_file_path = os.path.join(os.path.dirname(__file__), 'my-ca.crt')

response = requests.get('https://my-internal-server.example.com/', verify=ca_file_path)

This works fine up through Python 3.12. However, with Python 3.13, if the X509v3 Basic Constraints of the CA certificate are not marked as Critical, you will encounter the following error:

httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical (_ssl.c:1020)

To bypass this error in Python 3.13 without modifying the CA certificate, you can use the following:

import httpx
import ssl

ca_file_path = os.path.join(os.path.dirname(__file__), 'my-ca.crt')

context = ssl.create_default_context()
context.verify_flags &= ~ssl.VERIFY_X509_STRICT
context.load_verify_locations(ca_file_path)

response = httpx.get('https://my-internal-server.example.com/', verify=context)

This will allow you to bypass the issue.

Note: This is insecure.

Currently unrated
The author runs the application development company Cyberneura.
We look forward to discussing your development needs.

Categories

Archive