diff --git a/pep-0493.txt b/pep-0493.txt index 5a56fd116..6807edf9d 100644 --- a/pep-0493.txt +++ b/pep-0493.txt @@ -76,17 +76,6 @@ certificate validation in HTTPS client modules. It also provides additional recommendations to redistributors backporting these features to versions of Python prior to Python 2.7.9. -These designs are being proposed purely as tools for helping to manage the -transition to the new default certificate handling behaviour in the context -of Python 2.7. They are not being proposed as new features for Python 3, as -it is expected that the vast majority of client applications affected by this -problem without the ability to update the application itself will be Python 2 -applications. - -It would likely be desirable for a future version of Python 3 to allow default -certificate handling for secure protocols to be configurable on a per-protocol -basis, but that question is beyond the scope of this PEP. - Alternatives ------------ @@ -105,6 +94,21 @@ their customers. The main approaches available are: regardless of the formal status of the PEP +Scope Limitations +================= + +These changes are being proposed purely as tools for helping to manage the +transition to the new default certificate handling behaviour in the context +of Python 2.7. They are not being proposed as new features for Python 3, as +it is expected that the vast majority of client applications affected by this +problem without the ability to update the application itself will be Python 2 +applications. + +It would likely be desirable for a future version of Python 3 to allow the +default certificate handling for secure protocols to be configurable on a +per-protocol basis, but that question is beyond the scope of this PEP. + + Requirements for capability detection ===================================== @@ -124,6 +128,7 @@ distributions will offer them, only those that are providing a multi-stage migration process from the original Python 2.7 HTTPS handling to the new default behaviour. + Feature: Configuration API ========================== @@ -250,17 +255,99 @@ works the same way regardless of whether or not the interpreter is being run inside an activated Python virtual environment. +Backporting this PEP to earlier Python versions +=============================================== + +If this PEP is accepted, then commercial Python redistributors may choose to +backport the per-process configuration mechanisms defined in this PEP to base +versions older than Python 2.7.9, *without* also backporting PEP 476's change +to the default behaviour of the overall Python installation. + +Such a backport would differ from the mechanism proposed in this PEP solely in +the default behaviour when ``PYTHONHTTPSVERIFY`` was not set at all: it would +continue to default to skipping certificate validation. + +In this case, if the ``PYTHONHTTPSVERIFY`` environment variable is defined, and +set to anything *other* than ``'0'``, then HTTPS certificate verification +should be enabled. + +Feature detection +----------------- + +There's no specific attribute indicating that this situation applies. Rather, +it is indicated by the ``ssl._https_verify_certificates`` and +``ssl._https_verify_envvar`` attributes being present in a Python version that +is nominally older than Python 2.7.9. + +Specification +------------- + +Implementing this backport involves backporting the changes in PEP 466, 476 and +this PEP, with the following change to the handling of the +``PYTHONHTTPSVERIFY`` environment variable in the ``ssl`` module: + +* read the ``PYTHONHTTPSVERIFY`` environment variable when the module is first + imported into a Python process +* set the ``ssl._create_default_https_context`` function to be an alias for + ``ssl.create_default_context`` if this environment variable is present + and set to any value other than ``'0'`` +* otherwise, set the ``ssl._create_default_https_context`` function to be an + alias for ``ssl._create_unverified_context`` + +Example implementation +---------------------- + +:: + + _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 create_default_context + return _create_unverified_context + + _create_default_https_context = _get_https_context_factory() + + def _disable_https_default_verification(): + """Skip verification of HTTPS certificates by default""" + global _create_default_https_context + _create_default_https_context = _create_unverified_context + +Security Considerations +----------------------- + +This change would be a strict security upgrade for any Python version that +currently defaults to skipping certificate validation in standard library +HTTPS clients. The technical trade-offs to be taken into account relate largely +to the magnitude of the PEP 466 backport also required rather than to anything +security related. + +Interaction with Python virtual environments +-------------------------------------------- + +The default setting is read directly from the process environment, and hence +works the same way regardless of whether or not the interpreter is being run +inside an activated Python virtual environment. + + Backporting PEP 476 to earlier Python versions ============================================== -Some redistributors, most notably Linux distributions, may choose to backport -the PEP 476 HTTPS verification changes to modified Python versions based on -earlier Python 2 maintenance releases. In these cases, a configuration -mechanism is needed that provides: +The backporting approach described above leaves the default HTTPS certificate +verification behaviour of a Python 2.7 installation unmodified: verifying +certificates still needs to be opted into on a per-connection or per-process +basis. + +To allow the default behaviour of the entire installation to be modified +without breaking backwards compatibility, Red Hat designed a configuration +mechanism for the system Python 2.7 installation in Red Hat Enterprise Linux +7.2+ that provides: * an opt-in model that allows the decision to enable HTTPS certificate verification to be made independently of the decision to upgrade to the - Python version where the feature was first backported + operating system version where the feature was first backported * the ability for system administrators to set the default behaviour of Python applications and scripts run directly in the system Python installation * the ability for the redistributor to consider changing the default behaviour @@ -270,13 +357,19 @@ mechanism is needed that provides: As it only affects backports to earlier releases of Python 2.7, this change is not proposed for inclusion in upstream CPython, but rather is offered as -guidance to redistributors to reduce the likelihood of multiple mutually -incompatible approaches to backporting being adopted. +a recommendation to other redistributors that choose to offer a similar feature +to their users. -This approach SHOULD NOT be used for any Python installation that advertises -itself as providing Python 2.7.9 or later, as most Python users will have the -reasonable expectation that all such environments will validate HTTPS -certificates by default. +This PEP doesn't take a position on whether or not this particular change is a +good idea - rather, it suggests that *if* a redistributor chooses to go down +the path of making the default behaviour configurable in a version of Python +older than Python 2.7.9, then maintaining a consistent approach across +redistributors would be beneficial for users. + +However, this approach SHOULD NOT be used for any Python installation that +advertises itself as providing Python 2.7.9 or later, as most Python users +will have the reasonable expectation that all such environments will verify +HTTPS certificates by default. Feature detection @@ -392,7 +485,7 @@ locked down configuration: escalation attacks) The intent is that the *only* reason HTTPS verification should be getting -turned off system wide when using this approach is because: +turned off installation wide when using this approach is because: * an end user is running a redistributor provided version of CPython rather than running upstream CPython directly @@ -400,7 +493,7 @@ turned off system wide when using this approach is because: verifying HTTPS certificates by default than that being provided by the upstream project * either the redistributor or the local infrastructure administrator has - determined that it is appropriate to override the default upstream behaviour + determined that it is appropriate to retaing the default pre-2.7.9 behaviour (at least for the time being) Using an administrator controlled configuration file rather than an environment @@ -425,93 +518,12 @@ this backport for Python 2.7.5 can be found in the `CentOS git repository `__. -Backporting this PEP to earlier Python versions -=============================================== - -The configuration file based backport described above is designed to cover -backporting the PEP 476 changes to default certificate handling without the -additional configuration mechanisms defined in this PEP. - -If this PEP is accepted, then an additional backporting option becomes -available, which is to backport the per-process configuration mechanisms -defined in this PEP, without backporting the ability to change the default behaviour of the overall Python installation. - -Such a backport would differ from the mechanism proposed in this PEP solely in -the default behaviour when ``PYTHONHTTPSVERIFY`` was not set at all: it would -continue to default to skipping certificate validation. - -In this case, if the ``PYTHONHTTPSVERIFY`` environment variable is defined, and -set to anything *other* than ``'0'``, then HTTPS certificate verification -should be enabled. - - -Feature detection ------------------ - -There's no specific attribute indicating that this situation applies. Rather, -it is indicated by the ``ssl._https_verify_certificates`` and -``ssl._https_verify_envvar`` attributes being present in a Python version that -is nominally older than Python 2.7.9. - -Specification -------------- - -Implementing this backport involves backporting the changes in PEP 466, 476 and -this PEP, with the following change to the handling of the -``PYTHONHTTPSVERIFY`` environment variable in the ``ssl`` module: - -* read the ``PYTHONHTTPSVERIFY`` environment variable when the module is first - imported into a Python process -* set the ``ssl._create_default_https_context`` function to be an alias for - ``ssl.create_default_context`` if this environment variable is present - and set to any value other than ``'0'`` -* otherwise, set the ``ssl._create_default_https_context`` function to be an - alias for ``ssl._create_unverified_context`` - -Example implementation ----------------------- - -:: - - _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 create_default_context - return _create_unverified_context - - _create_default_https_context = _get_https_context_factory() - - def _disable_https_default_verification(): - """Skip verification of HTTPS certificates by default""" - global _create_default_https_context - _create_default_https_context = _create_unverified_context - -Security Considerations ------------------------ - -This change would be a strict security upgrade for any Python version that -currently defaults to skipping certificate validation in standard library -HTTPS clients. The technical trade-offs to be taken into account relate largely -to the magnitude of the PEP 466 backport also required rather than to anything -security related. - -Interaction with Python virtual environments --------------------------------------------- - -The default setting is read directly from the process environment, and hence -works the same way regardless of whether or not the interpreter is being run -inside an activated Python virtual environment. - - Recommendation for combined feature backports ============================================= If a redistributor chooses to backport the environment variable based configuration setting from this PEP to a modified Python version that also -implements the configuration file based PEP 476 , then the environment +implements the configuration file based PEP 476 backport, then the environment variable should take precedence over the system-wide configuration setting. This allows the setting to be changed for a given user or application, regardless of the installation-wide default behaviour.