[Python-checkins] peps: PEP 493: simplify detection of the capability

nick.coghlan python-checkins at python.org
Mon Jul 6 02:45:18 CEST 2015


https://hg.python.org/peps/rev/5f8f19025e19
changeset:   5902:5f8f19025e19
user:        Nick Coghlan <ncoghlan at gmail.com>
date:        Mon Jul 06 10:45:09 2015 +1000
summary:
  PEP 493: simplify detection of the capability

files:
  pep-0493.txt |  75 ++++++++++++++++++++++++++++++++-------
  1 files changed, 61 insertions(+), 14 deletions(-)


diff --git a/pep-0493.txt b/pep-0493.txt
--- a/pep-0493.txt
+++ b/pep-0493.txt
@@ -72,6 +72,25 @@
 Foundation or by a redistributor).
 
 
+Requirements for capability detection
+=====================================
+
+As these recommendations are intended to cover backports to earlier Python
+versions, the Python version number cannot be used as a reliable means for
+detecting them. Instead, the recommendations are defined to allow the presence
+or absence of the feature to be determined using the following technique::
+
+    python -c "import ssl; ssl._relevant_attribute"
+
+This will fail with `AttributeError` (and hence a non-zero return code) if the
+relevant capability is not available.
+
+The marker attributes are prefixed with an underscore to indicate the
+implementation dependent nature of these capabilities - not all Python
+distributions will offer them, only those that are providing a multi-stage
+migration process from the legacy HTTPS handling to the new default behaviour.
+
+
 Recommendation for an environment variable based security downgrade
 ===================================================================
 
@@ -91,6 +110,19 @@
 including those that advertise themselves as providing Python 2.7.9 or later.
 
 
+Required marker attribute
+-------------------------
+
+The required marker attribute on the ``ssl`` module when implementing this
+recommendation is::
+
+    _https_verify_envvar = 'PYTHONHTTPSVERIFY'
+
+This not only makes it straightforward to detect the presence (or absence) of
+the capability, it also makes it possible to programmatically determine the
+relevant environment variable name.
+
+
 Recommended modifications to the Python standard library
 --------------------------------------------------------
 
@@ -112,8 +144,10 @@
 
 ::
 
+    _https_verify_envvar = 'PYTHONHTTPSVERIFY'
+
     def _get_https_context_factory():
-        config_setting = os.environ.get('PYTHONHTTPSVERIFY')
+        config_setting = os.environ.get(_https_verify_envvar)
         if config_setting == '0':
             return _create_unverified_context
         return create_default_context
@@ -128,13 +162,10 @@
 does introduce a new downgrade attack against the default security settings
 that potentially allows a sufficiently determined attacker to revert Python
 to the vulnerable configuration used in CPython 2.7.8 and earlier releases.
-Such an attack requires the ability to modify the execution environment of
-a Python process prior to the import of the ``ssl`` module.
-
-Redistributors should balance this marginal increase in risk against the
-ability to offer a smoother migration path to their users when deciding whether
-or not it is appropriate for them to implement this per-application "opt out"
-model.
+However, such an attack requires the ability to modify the execution
+environment of a Python process prior to the import of the ``ssl`` module,
+and any attacker with such access would already be able to modify the
+behaviour of the underlying OpenSSL implementation.
 
 
 Recommendation for backporting to earlier Python versions
@@ -161,6 +192,19 @@
 certificates by default.
 
 
+Required marker attribute
+-------------------------
+
+The required marker attribute on the ``ssl`` module when implementing this
+recommendation is::
+
+    _cert_verification_config = '<path to configuration file>'
+
+This not only makes it straightforward to detect the presence (or absence) of
+the capability, it also makes it possible to programmatically determine the
+relevant configuration file name.
+
+
 Recommended modifications to the Python standard library
 --------------------------------------------------------
 
@@ -218,9 +262,10 @@
 
 ::
 
+    _cert_verification_config = '/etc/python/cert-verification.cfg'
+
     def _get_https_context_factory():
         # Check for a system-wide override of the default behaviour
-        config_file = '/etc/python/cert-verification.cfg'
         context_factories = {
             'enable': create_default_context,
             'disable': _create_unverified_context,
@@ -228,7 +273,7 @@
         }
         import ConfigParser
         config = ConfigParser.RawConfigParser()
-        config.read(config_file)
+        config.read(_cert_verification_config)
         try:
             verify_mode = config.get('https', 'verify')
         except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
@@ -268,7 +313,7 @@
   (at least for the time being)
 
 Using an administrator controlled configuration file rather than an environment
-variable has the essential feature of providing a smoother migraiton path, even
+variable has the essential feature of providing a smoother migration path, even
 for applications being run with the ``-E`` switch.
 
 
@@ -289,16 +334,18 @@
 
 ::
 
+    _https_verify_envvar = 'PYTHONHTTPSVERIFY'
+    _cert_verification_config = '/etc/python/cert-verification.cfg'
+
     def _get_https_context_factory():
         # Check for am environmental override of the default behaviour
-        config_setting = os.environ.get('PYTHONHTTPSVERIFY')
+        config_setting = os.environ.get(_https_verify_envvar)
         if config_setting is not None:
             if config_setting == '0':
                 return _create_unverified_context
             return create_default_context
 
         # Check for a system-wide override of the default behaviour
-        config_file = '/etc/python/cert-verification.cfg'
         context_factories = {
             'enable': create_default_context,
             'disable': _create_unverified_context,
@@ -306,7 +353,7 @@
         }
         import ConfigParser
         config = ConfigParser.RawConfigParser()
-        config.read(config_file)
+        config.read(_cert_verification_config)
         try:
             verify_mode = config.get('https', 'verify')
         except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):

-- 
Repository URL: https://hg.python.org/peps


More information about the Python-checkins mailing list