PEP 493: Clarify scope & deemphasise PEP 476 backport
* Scope limitations now have their own section, rather than being part of the Rationale section * reordered backport sections so PEP 493 backport is discussed prior to the PEP 476 backport * made it explicit that the PEP 476 section is aimed at "*IF* you backport this feature, do it *this* way", so simply not implementing that section at all is entirely PEP compliant
This commit is contained in:
parent
efb59d3cd6
commit
a0a5b34663
224
pep-0493.txt
224
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
|
|||
<https://git.centos.org/commit/rpms!python.git/refs!heads!c7>`__.
|
||||
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue