[Python-Dev] PYTHONHTTPSVERIFY env var

Donald Stufft donald at stufft.io
Mon May 11 12:23:11 CEST 2015

> On May 11, 2015, at 6:15 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 11 May 2015 at 19:22, M.-A. Lemburg <mal at egenix.com> wrote:
>> On 11.05.2015 11:13, Nick Coghlan wrote:
>>> I wouldn't be opposed to seeing that as an upstream Python 2.7.x
>>> feature, but agreement amongst redistributors on using a file-based
>>> approach is the main outcome I'm looking for.
>> Can't we have both ?
> I'd strongly advise against it, as we're deliberately increasing the
> attack surface area here by providing a potential path to carry out a
> downgrade attack on the HTTPS certificate verification by forcing it
> back to the old behaviour.
> The main existing environment variable based attack vector would be to
> manage to run a process with administrative privileges and
> SSL_CERT_DIR and/or SSL_CERT_FILE pointing to a certificate written to
> a user or world-writable directory by the attacker. Providing a "don't
> verify HTTPS" flag at the interpreter level would let an attacker skip
> the first step of writing the certificate file to disk somewhere,
> making a system compromise harder to detect. (An especially paranoid
> SSL implementation would disallow reading certs from locations that
> allow write access to non-administrative users, but I don't believe
> OpenSSL is that paranoid)
> By contrast, the configuration file shouldn't provide a new attack
> vector (or simplify any existing attack vector), as if you have the
> permissions needed to modify the config file, you likely also have the
> permissions needed to modify the system certificate store, and the
> latter is a *far* more interesting attack vector than a downgrade
> attack solely against Python.
> Thus the environment variable based off switch is neither necessary
> (as an administrator controlled configuration file can do the job),
> nor sufficient (it can't handle the -E switch), *and* it represents an
> increase in the attack surface area relative to a Python
> implementation without the capability.
>> I don't think that we can wait for a whole PEP process to
>> run through
> Matrix multiplication made it through the PEP process in 8 days. If we
> do this as a redistributor recommendation rather than attempting to
> get it into upstream Python 2.7, we could potentially propose you take
> on the role of BDFL-Delegate and mark it as Accepted as soon as the
> two of us agree on a common approach.
> The reason I think that's a reasonable way forward is because we
> already know there are folks opposed to making the change upstream. If
> the PEP just provides recommendations for redistributors that *do*
> decide to provide a "global off switch" to revert to the old
> behaviour, then the perspective of the folks opposed to the feature is
> respected by the fact that this is a feature some redistributors *may*
> choose to add to provide a smoother migration path to more secure
> default HTTPS handling, rather than something upstream provides by
> default.
> I assume the Debian, Ubuntu and Suse folks won't care, as they have
> all already decided against backporting the change to their long term
> support releases where the compatibility break would pose a problem
> (and I can certainly sympathise with that perspective given the
> dependency on backporting the PEP 466 SSL changes first, and the work
> involved in seeking consensus on a smoother migration path from the
> old default to the new one).
> It would be nice to hear from ActiveState, Enthought & Continuum
> Analytics as well, but if they don't chime in here, I don't see any
> particular need to go chasing them explicitly.
>> to fix this regression in 2.7.9.
> We made the decision when PEP 476 was accepted that this change turned
> a silent security failure into a noisy one, rather than being a
> regression in its own right. PEP 493 isn't about disagreeing with that
> decision, it's about providing a smoother upgrade path in contexts
> where letting the security failure remain silent is deemed to be
> preferred in the near term.

I don't really agree that the decision to disable TLS is an environment one,
it's really a per application decision. This is why I was against having some
sort of global off switch for all of Python because just because one
application needs it turned off doesn't mean you want it turned off for another
Python application. You might have some script that is interacting with a
custom internal server which doesn’t have a valid TLS certificate but then you
also have pip* installed which is reaching out to PyPI and downloading code
from the internet. You might want to disable TLS verification for the first but
you almost certainly don't want it to disable TLS verification for the second

In this regard I think that environment variables are somewhat better because
they are far easier to set per application instead of in a way that affects
every python program. Per application is the *right* scope for this setting,
especially in a system where people may or may not realize what is written in
Python and what isn't. I think it's absolutely wrong to give people a footgun
in the terms of a switch that turns off all of Python's TLS verification when
for many applications the fact they use Python is simply an implementation

That being said, since it's not being included in Python core and it's only
some patch that some downstream's are going to apply I also don't really care
that much because it's not going to effect me and if it turns out to be a bad
idea and a footgun like I think it is, then the blame can rest on those
downstreams and not us :)

I'm also not a fan of the environment variable either really for a lot of the
reasons you've outlined here.

* Ignoring the fact that pip has (via requests/urllib3) worked around this
  deficiency in Python and isn't going to be affected by this configuration
  switch at all.

Donald Stufft
PGP: 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.python.org/pipermail/python-dev/attachments/20150511/487da866/attachment.sig>

More information about the Python-Dev mailing list