I agree wholeheartedly with the sentiment behind this PEP, but I have concerns about the implementation.  If we introduce new APIs into the ssl module then we will see packages and applications that depend on Python 2.7.7+, just like with the introduction of bool in 2.2.1.  This will be a mess unless adoption of new Python minor versions is swift and consistent.  The PEP says that new features should be testable with feature detection, but how far does that go?  The Python 3 NPN interface is a method of SSLContext, which didn't exist in 2.7.  Do we backport the entire SSLContext interface in a minor release, or introduce a new NPN interface that is not based on SSLContext just for older Pythons?

In my experience most deployments of Python apps have better systems in place to deal with packages installed from PyPI than new versions of Python itself.  Therefore it might be better to follow the lead of the unittest2 module and introduce a new ssl2 module that tracks the most recent version of Python's ssl module.

My counter-proposal is:
* Introduce a new module 'ssl2' which is essentially a backport of the current release's ssl module for all old versions of Python that anyone cares to support.
* Third-party applications and libraries targeting anything but the latest version of Python are advised to use ssl2 instead of ssl (this might also be a good opportunity to bless certifi or an equivalent).
* Minor releases of Python are allowed to make any security-related change that does not change any public interfaces (e.g. linking against a new version of openssl, or disabling SSLv2)
* New interfaces in security-related modules are allowed only if those new interfaces are used by other stdlib modules (since stdlib modules are the only place where ssl2 is off-limits).  For example, a backport of match_hostname could go in if httplib or urllib used it.  NPN/ALPN would not be allowed under this rule since there is no stdlib code that uses them; third-party SPDY or HTTP/2 code would have to use ssl2 to get this interface.

In this world, libraries like requests or tornado that want to use advanced ssl features can simply declare a dependency on ssl2, instead of saying "we require Python 2.7.7+, 3.2.6+, etc".  

In spite of my reservations about this PEP, I'd still love to see SSL improvements in 2.7 in any form.  I'm currently planning a port for Tornado's ssl usage from the stdlib ssl module to PyOpenSSL (in order to get SNI and NPN/ALPN features), and I'd really rather not have to convert to a completely incompatible interface.

-Ben




On Sat, Mar 22, 2014 at 5:11 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Folks,

I have just posted a proposal to change the way we treat enhancements
that relate to Python's support for network security enhancements. I
now see these as categorically different from most other enhancements,
as they have implications for the evolution of internet security as a
whole, rather than being limited to affecting the security of
individual applications written in Python.

It is similar to the previous IDLE policy exception PEP, where we
decided that cross version consistency of IDLE superseded the general
policy against backporting enhancements to maintenance branches.

This new PEP proposes a similar exception for network security related
changes, such that the *capabilities* of all still maintained versions
should be kept equivalent, with only the *default settings* varying
across up to date feature releases. The policy is also designed to
make it easier for us to ratchet up the default security settings in
future feature releases.

However, it's more complex than the IDLE PEP (since it's more
invasive), and there are still a few open questions listed. This topic
involves a complex balance between encouraging and supporting good
security practices and limiting the risk of failures for users
upgrading to new maintenance releases, so I'd ask that folks take time
to read and consider the implications of the full PEP in the broader
context of today's internet before posting comments on specific
details, or indicating a preference one way or the other in terms of
the overall proposal.

Full PEP included inline below, and available in more readable form at
http://www.python.org/dev/peps/pep-0466/

Regards,
Nick.

PEP: 466
Title: Network Security Enhancement Exception for All Branches
Version: $Revision$
Last-Modified: $Date$
Author: Nick Coghlan <ncoghlan@gmail.com>,
Status: Draft
Type: Informational
Content-Type: text/x-rst
Created: 23-Mar-2014
Post-History: 23-Mar-2014


Abstract
========

Most CPython tracker issues are classified as errors in behaviour or
proposed enhancements. Most patches to fix behavioural errors are
applied to all active maintenance branches.  Enhancement patches are
restricted to the default branch that becomes the next Python version.

This PEP relaxes the latter restriction allowing enhancements to be applied
to maintenance branches for standard library components that have
implications for the overall security of the internet. In particular, the
exception will apply to:

* the ``ssl`` module
* the ``hashlib`` module
* the ``hmac`` module
* the ``sha`` module (Python 2 only)
* the components of other networking modules that make use of these modules
* the components of the ``random`` and ``os`` modules that are relevant to
  cryptographic applications
* the version of OpenSSL bundled with the binary installers

Changes to these modules will still need to undergo normal backwards
compatibility assessments, but new features will be permitted where
appropriate, making it easier to implement secure networked software in
Python, even for software that needs to remain compatible with older feature
releases of Python.


Exemption Policy
================

Under this policy, the following network security related modules are
granted a blanket exemption to the restriction against adding new features
in maintenance releases:

* the ``ssl`` module
* the ``hashlib`` module
* the ``hmac`` module
* the ``sha`` module (Python 2 only)

This exemption applies to *all* proposals to backport backwards compatible
features in these modules to active maintenance branches. This choice is
made deliberately to ensure that the "feature or fix?" argument isn't simply
replaced by a "security related or not?" argument. These particular modules
are inherently security related, and all enhancements to them improve
Python's capabilities as a platform for development of secure networked
software.

As part of this policy, permission is also granted to upgrade to newer
feature releases of OpenSSL when preparing the binary installers
for new maintenance releases of CPython.

In addition to the above blanket exemption, a conditional exemption is
granted for these modules that may include some network security related
features:

* the ``os`` module (primarily ``os.urandom``)
* the ``random`` module
* networking related modules that depend on one or more of the network
  security related modules listed above

This more limited exemption for these modules requires that the *specific*
enhancement being proposed for backporting needs to be justified as being
network security related. If the enhancement under discussion is designed
to take advantage of a new feature in one of the network security related
modules, then that will be taken as implying that the enhancement is
security related.


Backwards Compatibility Considerations
======================================

This PEP does *not* grant any general exemptions to the usual backwards
compatibility policy for maintenance releases. Instead, it is designed
to make it easier to provide more "secure by default" behaviour in future
feature releases, while still limiting the risk of breaking currently
working software when upgrading to a new maintenance release.

In *all* cases where this policy is applied to backport enhancements to
maintenance releases, it MUST be possible to write cross-version compatible
code that operates by "feature detection" (for example, checking for
particular attributes in the module), without needing to explicitly check
the Python version.

It is then up to library and framework code to provide an appropriate error
message or fallback behaviour if a desired feature is found to be missing.

Affected APIs SHOULD be designed to allow library and application code to
perform the following actions after detecting the presence of a relevant
network security related feature:

* explicitly opt in to more secure settings (to allow the use of enhanced
  security features in older versions of Python)
* explicitly opt in to less secure settings (to allow the use of newer Python
  versions in lower security environments)
* determine the default setting for the feature (this MAY require explicit
  Python version checks to determine the Python feature release, but MUST
  NOT depend on the specific maintenance release)


Documentation Requirements
==========================

All modules that take advantage of this policy to backport network
security related enhancements to earlier Python versions MUST include
a "Security Considerations" section in their documentation.

In addition to any other module specific contents, this section MUST
enumerate key security enhancements and fixes (with CVE identifiers where
applicable), and the


Evolution of this Policy
========================

The key requirement for a module to be considered for inclusion in this
policy (whether under a blanket or conditional exemption) is that it must
have security implications *beyond* the specific application that is written
in Python and the system that application is running on. Thus the focus on
network security protocols and related cryptographic infrastructure - Python
is a popular choice for the development of web services and clients, and
thus the capabilities of widely used Python versions have implications for
the security design of other services that may be using newer versions of
Python or other development languages.

The intent behind this requirement is to minimise any impact that the
introduction of this policy may have on the stability and compatibility of
maintenance releases. It would be thoroughly counterproductive if end
users became as cautious about updating to new Python maintenance releases
as they are about updating to new feature releases.


Motivation and Rationale
========================

This PEP can be seen as a more targeted version of the "faster standard
library release cycle" proposals discussed in PEP 407 and PEP 413,
focusing specifically on those areas which have implications beyond the
Python community.

The creation of this PEP was prompted primarily by the aging SSL support in
the Python 2 series. As of March 2014, the Python 2.7 SSL module is
approaching four years of age, and the SSL support in the still popular
Python 2.6 release had its feature set locked six years ago.

These are simply too old to provide a foundation that can be recommended
in good conscience for secure networking software that operates over the
public internet, especially in an era where it is becoming quite clearly
evident that advanced persistent security threats are even more widespread
and more indiscriminate in their targeting than had previously been
understood.

While the use of the system OpenSSL installation addresses many of these
concerns on Linux platforms, it doesn't address all of them, and in the
case of the binary installers for Windows and Mac OS X that are published
on python.org, the version of OpenSSL used is entirely within the control
of the Python core development team.

With increased popularity comes increased responsibility, and this policy
is about recognising the fact that Python's popularity and adoption has now
reached a level where some of our design and policy decisions have
significant implications beyond the Python development community.

As one example, the Python 2 ``ssl`` module does not support the Server
Name Identification standard. While it is possible to obtain SNI support
by using the third party ``requests`` client library, actually doing so
currently requires using not only ``requests`` and its embedded dependencies,
but also half a dozen or more additional libraries. The lack of support
in the Python 2 series thus serves as an impediment to making effective
use of SNI on servers, as Python 2 clients will frequently fail to handle
it correctly.

Another more critical example is the lack of SSL hostname matching in the
Python 2 standard library - it is currently necessary to rely on a third
party library, such as ``requests`` or ``backports.ssl_match_hostname`` to
obtain that functionality in Python 2.

The Python 2 series also remains more vulnerable to remote timing attacks
on security sensitive comparisons than the Python 3 series, as it lacks a
standard library equivalent to the timing attack resistant
``hmac.compare_digest()`` function. While appropriate secure comparison
functions can be implemented in third party extensions, may users don't
even consider the problem and use ordinary equality comparisons instead
- while a standard library solution doesn't automatically fix that problem,
it *does* make the barrier to resolution much lower once the problem is
pointed out.

My position on the ongoing transition from Python 2 to Python 3 has long
been that Python 2 remains a supported platform for the core development
team, and that commercial support will remain available well after upstream
maintenance ends. However, in the absence of this network security
enhancement policy, that position is difficult to justify when it comes to
software that operates over the public internet. Just as many developers
consider it too difficult to develop truly secure modern networked software
in C/C++ (largely due to the challenges associated with manual
memory management), I consider it too difficult to develop truly secure
modern networked software using the Python 2 series without introducing this
network security enhancement policy, as doing so would mean reimplementing
substantial portions of the standard library as third party modules to gain
access to the newer underlying network security protocols and mechanisms,
and then injecting those into the module namespace to override their
standard library counterparts.

Requiring that latent defects in an application's Unicode correctness be
addressed in order to migrate to Python 3 is not a reasonable alternative
recommendation, especially given the likely existence of legacy code that
lacks the kind of automated regression test suite needed to help support
a migration from Python 2 to Python 3. The key point of this PEP is that
those situations affect more people than just the developers and users of
the affected application: their existence becomes something that developers
of secure networked services need to take into account as part of their
security design. By making it more feasible to enhance the security of the
Python 2 series, we can help contribute to the evolution of a more secure
internet for all concerned.

For the Python 2 series, this proposal will most obviously impact the
remaining maintenance releases of Python 2.7. However, commercial
redistributors that continue to offer full support for Python 2.6, and will
also do so for Python 2.7 after upstream maintenance ends, may choose
to take this policy into account when deciding what changes to backport to
their own maintenance updates. Providing commercial redistributors such
as ActiveState, Attachmate, Canonical, Continuum Analytics, Enthought, and
Red Hat that option is one of the benefits offered by requiring feature
detection based forward compatibility for the modules covered by this policy.


Open Questions
==============

* What are the risks associated with allowing OpenSSL to be updated to
  new feature versions in the Windows and Mac OS X binary installers for
  maintenance releases?

* Are there any other security relevant modules that should be covered
  by either a blanket or conditional exemption?

* Should we enumerate a specific list of "other networking modules" rather
  than leaving it implicit?


Acknowledgement
===============

Thanks to Christian Heimes for his recent efforts on greatly improving
Python's SSL support in the Python 3 series, and a variety of members of
the Python community for helping me to better understand the implications
of the default settings we provide in our SSL modules, and the impact that
tolerating the use of SSL infrastructure that was defined in 2010
(Python 2.7) or even 2008 (Python 2.6) potentially has for the security
of the web as a whole.

Christian and Donald Stufft also provided valuable feedback on a preliminary
draft of this proposal.


Copyright
=========

This document has been placed in the public domain.



..
   Local Variables:
   mode: indented-text
   indent-tabs-mode: nil
   sentence-end-double-space: t
   fill-column: 70
   coding: utf-8
   End:


--
Nick Coghlan   |   ncoghlan@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/ben%40bendarnell.com