From 4c48f704926f39861dd913c5f99f71564bb5c6a9 Mon Sep 17 00:00:00 2001 From: Vinay Kumar Date: Wed, 26 Aug 2026 11:42:03 +0530 Subject: [PATCH] Fix SSL certificate verification on macOS This fixes https://github.com/httpie/cli/issues/1632 where HTTPie fails to verify SSL certificates on macOS even though requests works fine in the same environment. The root cause is that urllib3.util.ssl_.create_urllib3_context() creates SSL contexts without CA certificates, which causes certificate verification to fail. This fix ensures that when verify=True, we load the default certificates if needed. Fixes the issue by: 1. Ensuring certificates are loaded when verify=True 2. Adding a safety check for contexts that might have 0 certificates 3. Handling potential exceptions gracefully 4. Preserving backward compatibility --- httpie/ssl_.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/httpie/ssl_.py b/httpie/ssl_.py index 6b3ef38cf6..a3c33422ab 100644 --- a/httpie/ssl_.py +++ b/httpie/ssl_.py @@ -77,11 +77,26 @@ def _create_ssl_context( ciphers=ciphers, ssl_version=resolve_ssl_version(ssl_version), # Since we are using a custom SSL context, we need to pass this - # here manually, even though it’s also passed to the connection + # here manually, even though it's also passed to the connection # in `super().cert_verify()`. cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE ) - ensure_default_certs_loaded(ssl_context) + # Ensure default certificates are loaded for proper SSL verification + # This addresses https://github.com/httpie/cli/issues/1632 + if verify: + # First try the existing ensure_default_certs_loaded function + ensure_default_certs_loaded(ssl_context) + + # Additional safety check for cases where certificates might not be loaded + # This handles the specific issue where create_urllib3_context() + # creates a context with 0 certificates + if hasattr(ssl_context, 'load_default_certs') and not ssl_context.get_ca_certs(): + try: + ssl_context.load_default_certs() + except Exception: + # If loading fails, continue with what we have + # This preserves backward compatibility + pass return ssl_context @classmethod @@ -106,4 +121,4 @@ def _is_key_file_encrypted(key_file): # We used to import the default set of TLS ciphers from urllib3, but they removed it. # Instead, now urllib3 uses the list of ciphers configured by the system. # -DEFAULT_SSL_CIPHERS_STRING = ':'.join(HTTPieHTTPSAdapter.get_default_ciphers_names()) +DEFAULT_SSL_CIPHERS_STRING = ':'.join(HTTPieHTTPSAdapter.get_default_ciphers_names()) \ No newline at end of file