peps: f602a47ea795 (original) (raw)

--- a/pep-0493.txt +++ b/pep-0493.txt @@ -1,78 +1,91 @@ PEP: 493 -Title: HTTPS verification recommendations for Python 2.7 redistributors +Title: HTTPS verification migration tools for Python 2.7 Version: RevisionRevisionRevision Last-Modified: DateDateDate Author: Nick Coghlan ncoghlan@gmail.com, Robert Kuska rkuska@redhat.com, Marc-André Lemburg mal@lemburg.com Status: Draft -Type: Informational +Type: Standards Track Content-Type: text/x-rst Created: 10-May-2015 +Python-Version: 2.7.12 Post-History: 06-Jul-2015, 11-Nov-2015, 24-Nov-2015 Abstract ======== -PEP 476 updated Python's default handling of HTTPS certificates to be -appropriate for communication over the public internet. The Python 2.7 long -term maintenance series was judged to be in scope for this change, with the -new behaviour introduced in the Python 2.7.9 maintenance release. +PEP 476 updated Python's default handling of HTTPS certificates in client +modules to align with certificate handling in web browsers, by validating +that the certificates received belonged to the server the client was attempting +to contact. The Python 2.7 long term maintenance series was judged to be in +scope for this change, with the new behaviour introduced in the Python 2.7.9 +maintenance release. -This PEP provides recommendations to downstream redistributors wishing to -provide a smoother migration experience when helping their users to manage -this change in Python's default behaviour. - -Note that this PEP is not currently accepted, so it is a proposed -recommendation, rather than an active one. +This has created a non-trivial barrier to adoption for affected Python 2.7 +maintenance releases, so this PEP proposes additional Python 2.7 specific +features that allow system administrators and other users to more easily +decouple the decision to verify server certificates in HTTPS client modules +from the decision to update to newer Python 2.7 maintenance releases. Rationale ========= -PEP 476 changed Python's default behaviour to better match the needs and -expectations of developers operating over the public internet, a category -which appears to include most new Python developers. It is the position of -the authors of this PEP that this was a correct decision. +PEP 476 changed Python's default behaviour to align with expectations +established by web browsers in regards to the semantics of HTTPS URLs: +starting with Python 2.7.9 and 3.4.3, HTTPS clients in the standard library +validate server certificates by default. However, it is also the case that this change does cause problems for infrastructure administrators operating private intranets that rely on self-signed certificates, or otherwise encounter problems with the new default certificate verification settings. -The long term answer for such environments is to update their internal -certificate management to at least match the standards set by the public -internet, but in the meantime, it is desirable to offer these administrators -a way to continue receiving maintenance updates to the Python 2.7 series, -without having to gate that on upgrades to their certificate management -infrastructure. +To manage these kinds of situations, web browsers provide users with "click +through" warnings that allow the user to add the server's certificate to the +browser's certificate store. Network client tools like curl and wget +offer options to switch off certificate checking entirely (by way of +curl --insecure and wget --no-check-certificate, respectively). -PEP 476 did attempt to address this question, by covering how to revert the -new settings process wide by monkeypatching the ssl module to restore the +At a different layer of the technology stack, Linux security modules like +SELinux and AppArmor, while enabled by default by distribution vendors, +offer relatively straightforward mechanisms for turning them off. + +At the moment, no such convenient mechanisms exist to disable Python's +default certificate checking for a whole process. + +PEP 476 did attempt to address this question, by covering how to revert to the +old settings process wide by monkeypatching the ssl module to restore the old behaviour. Unfortunately, the sitecustomize.py based technique proposed to allow system administrators to disable the feature by default in their Standard Operating Environment definition has been determined to be -insufficient in at least some cases. The specific case of interest to the -authors of this PEP is the one where a Linux distributor aims to provide -their users with a +insufficient in at least some cases. The specific case that led to the +initial creation of this PEP is the one where a Linux distributor aims to +provide their users with a smoother migration path <https://bugzilla.redhat.com/show_bug.cgi?id=1173041>__ than the standard one provided by consuming upstream CPython 2.7 releases directly, but other potential challenges have also been pointed out with updating embedded Python runtimes and other user level installations of Python. Rather than allowing a plethora of mutually incompatibile migration techniques -to bloom, this PEP proposes two alternative approaches that redistributors -may take when addressing these problems. Redistributors may choose to implement -one, both, or neither of these approaches based on their assessment of the -needs of their particular userbase. +to bloom, this PEP proposes an additional feature to be added to Python 2.7.12 +to make it easier to revert a process to the past behaviour of skipping +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 as a recommendation for redistributors, rather -than as new upstream features, as they are needed purely to support legacy -environments migrating from older versions of Python 2.7. Neither approach -is being proposed as an upstream Python 2.7 feature, nor as a feature in any -version of Python 3 (whether published directly by the Python Software -Foundation or by a redistributor). +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 ------------ @@ -84,20 +97,20 @@ their customers. The main approaches ava

+ +If called without arguments, or with enable set to a true value, then +standard library client modules will subsequently verify HTTPS certificates by default, otherwise they will skip verification. + +If called with enable set to a false value, then standard library client +modules will subsequently skip verifying HTTPS certificates by default. + +Security Considerations +----------------------- + +The inclusion of this feature will allow security sensitive applications to +include the following forward-compatible snippet in their code:: +

+ +Some developers may also choose to opt out of certificate checking using +ssl._verify_https_certificates(enable=False). This doesn't introduce any +major new security concerns, as monkeypatching the affected internal APIs was +already possible. -Recommendation for an environment variable based security downgrade -=================================================================== +Feature: environment based configuration +======================================== -Some redistributors may wish to provide a per-application option to disable -certificate verification in selected applications that run on or embed CPython -without needing to modify the application itself. - -In these cases, a configuration mechanism is needed that provides: +This change is proposed for inclusion in CPython 2.7.12 and later CPython 2.7.x +releases. It consists of a new PYTHONHTTPSVERIFY environment variable that +allows the default verification to be disabled without modifying the +application source code (which may not even be available in cases of +bytecode-only application distribution) -* an opt-out model that allows certificate verification to be selectively

+* the ssl._https_verify_envvar attribute, giving the name of environment

+

+

+

+ +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 +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. + Example implementation ----------------------