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
|
recommendations to redistributors backporting these features to versions of
|
||||||
Python prior to Python 2.7.9.
|
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
|
Alternatives
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -105,6 +94,21 @@ their customers. The main approaches available are:
|
||||||
regardless of the formal status of the PEP
|
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
|
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
|
migration process from the original Python 2.7 HTTPS handling to the new
|
||||||
default behaviour.
|
default behaviour.
|
||||||
|
|
||||||
|
|
||||||
Feature: Configuration API
|
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.
|
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
|
Backporting PEP 476 to earlier Python versions
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
Some redistributors, most notably Linux distributions, may choose to backport
|
The backporting approach described above leaves the default HTTPS certificate
|
||||||
the PEP 476 HTTPS verification changes to modified Python versions based on
|
verification behaviour of a Python 2.7 installation unmodified: verifying
|
||||||
earlier Python 2 maintenance releases. In these cases, a configuration
|
certificates still needs to be opted into on a per-connection or per-process
|
||||||
mechanism is needed that provides:
|
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
|
* an opt-in model that allows the decision to enable HTTPS certificate
|
||||||
verification to be made independently of the decision to upgrade to the
|
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
|
* the ability for system administrators to set the default behaviour of Python
|
||||||
applications and scripts run directly in the system Python installation
|
applications and scripts run directly in the system Python installation
|
||||||
* the ability for the redistributor to consider changing the default behaviour
|
* 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
|
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
|
not proposed for inclusion in upstream CPython, but rather is offered as
|
||||||
guidance to redistributors to reduce the likelihood of multiple mutually
|
a recommendation to other redistributors that choose to offer a similar feature
|
||||||
incompatible approaches to backporting being adopted.
|
to their users.
|
||||||
|
|
||||||
This approach SHOULD NOT be used for any Python installation that advertises
|
This PEP doesn't take a position on whether or not this particular change is a
|
||||||
itself as providing Python 2.7.9 or later, as most Python users will have the
|
good idea - rather, it suggests that *if* a redistributor chooses to go down
|
||||||
reasonable expectation that all such environments will validate HTTPS
|
the path of making the default behaviour configurable in a version of Python
|
||||||
certificates by default.
|
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
|
Feature detection
|
||||||
|
@ -392,7 +485,7 @@ locked down configuration:
|
||||||
escalation attacks)
|
escalation attacks)
|
||||||
|
|
||||||
The intent is that the *only* reason HTTPS verification should be getting
|
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
|
* an end user is running a redistributor provided version of CPython rather
|
||||||
than running upstream CPython directly
|
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
|
verifying HTTPS certificates by default than that being provided by the
|
||||||
upstream project
|
upstream project
|
||||||
* either the redistributor or the local infrastructure administrator has
|
* 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)
|
(at least for the time being)
|
||||||
|
|
||||||
Using an administrator controlled configuration file rather than an environment
|
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>`__.
|
<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
|
Recommendation for combined feature backports
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
If a redistributor chooses to backport the environment variable based
|
If a redistributor chooses to backport the environment variable based
|
||||||
configuration setting from this PEP to a modified Python version that also
|
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.
|
variable should take precedence over the system-wide configuration setting.
|
||||||
This allows the setting to be changed for a given user or application,
|
This allows the setting to be changed for a given user or application,
|
||||||
regardless of the installation-wide default behaviour.
|
regardless of the installation-wide default behaviour.
|
||||||
|
|
Loading…
Reference in New Issue