Published: ven. 15 septembre 2017
I am working on the Python security for years, but I never wrote anything about
that. Let's fix this!
I am part of the Python Security Response Team (PSRT): I get emails sent to
email@example.com. I try to analyze each report to validate that the bug
is reproductible, find impacted Python versions and start to discuss how to fix
the vulnerability. In some cases, the reported issue is not a security
vulnerability, is not related to CPython, or sometimes is already fixed. We
also get reports about CPython, but also the web sites and other projects
related to Python.
Warning: I don't represent the PSRT, I speak for my own!
Vulnerabilities sent to PSRT
In this article, I will focus on vulnerabilities impacting CPython: the C and
Python code of CPython core and the standard library.
When vulnerabilities are obvious bugs, they are quickly fixed. Done.
But it's not uncommon that fixing a vulnerability impacts the backward
compatibility which is a major concern of CPython core developers. There is
also a risk of rejecting legit input data because the added checks are too
strict. We have to be very careful and so fixing vulnerabilities can take
weeks, if not months in the worst case.
While CPython has few active core developers, the PSRT has even lesser active
members to handle incoming reports. We are volunteers, so please be kind and
Example of a complex fix
urllib FTP protocol stream injection
vulnerability was reported to the PSRT at 2016-01-15. The fix was only merged
First, it was not obvious how the vulnerability can be exploited, nor if it
should be fixed.
Then it was not obvious if the vulnerability should be fixed in the urllib
module or in the ftplib module.
Even if the bug was public, it didn't get much attention. Since I don't know
well how the urllib module, I wrote an email to the python-dev mailing
Need help to fix urllib(.parse) vulnerabilities.
I proposed a fix for the urllib module:
Reject newline character (U+000A) in
URLs in urllib.parse. But it was
rejected, since it was the wrong approach and my checks were too strict in many
cases (rejected legit requests).
The final fix rejects
\b and \r newline characters in the putline()
method of the ftplib module.
Track known and fixed CPython vulnerabilities
Currently, not least that six branches still get security fixes!
master: the development branch
Last year, I added a table to the Python developer guide to help me to track
the status of each branch: see the
Status of Python branches.
This year, I created a tool to help me to track known CPython vulnerabilities:
python-security project (hosted
at GitHub). The vulnerabilities.yaml file
is a YAML file with one section per vulnerability. Each vulnerability has
a title, link to the Python bug, disclosure date, reported date, commits, etc.
The tool gets the date of commits and the Git tags which contains the commit
to infer the first Python versions of each branch which contain the fix. It
also build a timeline to help to understand how the vulnerability was handled.
I also wanted to be more transparent on how we handle vulnerabilities and our
velocity to fix them.
Honestly, I was disappointed that it took so long to fix some vulnerabilities
in the past. Hopefully, it seems like we are more reactive nowadays!
Example of a fixed vulnerability
CVE-2016-5699: HTTP header injection.
Right now, Python 3.3 is still vulnerable (my fix was commited, I am now
waiting Python 3.3.7 which is coming at the end of september).
Since the vulnerability was reported, it took 108 days to merge the fix, 72
more days (total 180 days) for the first release including the fix (Python
Sadly, the PSRT doesn't compute a severity of vulnerabilities yet.
Hopefully, for this vulnerability, web frameworks were able to workaround the
vulnerability by input sanitization.
Backport all fixes
Last months, I backported fixes to the six branches which still accept security
fixes, to respect the contract with our users: we are doing our best to protect
The good news is that with Python 2.7.14 and Python 3.3.7 releases scheduled
this month, all major security vulnerabilities will be fixed in all maintained
Some fixes were not backported on purpose. For example, the
Hash not properly randomized
vulnerability requires to change the hash algorithm and we decided to not touch
Python 2.7 and 3.3 for backward compatibility reasons (don't break code relying
on the exact hash function). The issue was fixed in Python 3.4 by using the
SipHash hash algorithm which uses a hash secret (generated randomly by Python
Python security documentation
Last months, I also started to collect random notes about the Python security.
python-security.readthedocs.io documentation and send me feedback!