SSL: CERTIFICATE_VERIFY_FAILED with Python2.7/3
To enhance flexibility and address specific use cases, modifications will be made to the ssl module instead of consistently relying on ssl.create_default_context. The updated approach involves checking the PYTHONHTTPSVERIFY
environment variable upon the module’s initial import in a Python process. The ssl._create_default_https_context function will then be configured as follows:
- If the environment variable is present and set to ‘0’,
ssl._create_default_https_context
will be an alias for ssl._create_unverified_context. - Otherwise,
ssl._create_default_https_context
will be an alias forssl.create_default_context
, adhering to the usual behavior.
Here is an example implementation:
import os
import sys
import ssl
_https_verify_envvar = 'PYTHONHTTPSVERIFY'
def _get_https_context_factory():
if not sys.flags.ignore_environment:
config_setting = os.environ.get(_https_verify_envvar)
if config_setting == '0':
return ssl._create_unverified_context
return ssl.create_default_context
ssl._create_default_https_context = _get_https_context_factory()
It’s essential to consider security implications. While this approach provides flexibility, it introduces a potential downgrade attack against default security settings. Specifically, a determined attacker could revert Python to the default behavior of CPython 2.7.8 and earlier releases.
Key points to note:
- Security-sensitive applications are advised to define their SSL context.
- The migration features outlined in this proposal are not incorporated into Python 3.
- The introduced attack surface is minimal, as executing such an attack requires modifying the Python process’s execution environment before importing the ssl module. Any attacker with this level of access could already manipulate the behavior of underlying components, including OpenSSL and the dynamic library loader.
Temporary solution
As a temporary solution (not recommended for security reasons), you have the option to disable certificate verification by configuring the PYTHONHTTPSVERIFY
environment variable and setting it to 0:
export PYTHONHTTPSVERIFY=0
Comments
Post a Comment