James Bennett worked already with Django for 9 years. And especially: he’s been involved with Django’s security releases for 8 years now. So this talk is about a history of django and security and how django tries to protect you. And where django screwed up and what you can learn from it.
Bottom line: security is hard. There are always things that can be improved, always things that could be more secure.
He showed the first ever django security bug. And the last one (number 49). The last one had a proper full release, the first one told you to overwrite one specific file. The first issue played down the problem a bit, the last one didn’t. See the full list of all security issues.
In 2007, there was still an informal security process. In 2008, django 1.0, django started autoescaping in the templates. Quite controversial with a long discussion, but it was decided it was so important that it was enabled by default. In 2010, django 1.2, modern csrf protection got added. Security by default. Better to be safe out of the box.
Next big one was django 1.4. Hashing, crypto, signed cookies, clickjacking, sensitive errors. James says this is the first django release that took security seriously. And... 1.4 was the first with a formal security process.
2013, django 1.5/1.6. Host header hardening, increased hash iterations and hash truncation. “Host header hardening” was one of the problematic areas, he’ll talk about that later on.
2014, 1.7: system check framework. 2015, 1.8: security middleware and a deployment checker.
Back to the formal security process. Short version: mail firstname.lastname@example.org, they’ll verify it. If verified, they fix it. A CVE number is requested and releases are made. The fixing and discussion happens on a private issue tracker and a private branch. The goal is to get a security release out quickly and reliably. And to make sure most of the security bugs are told to them via security@ instead of publicly: responsible disclosure.
Look at the OWASP top 10. Django protects you from all of the items on that list by default. Cross site scripting, database injection, csrf. For instance. The only thing django doesn’t force you to do yet is to use https.
We go above and beyond, however. Very advanced password hashing. GPG signed django releases. And more and more.
Most of the problems are caused by overlooking something and good intentions. He mentioned a couple of improvements to django, like arbitrarily long passwords. That’s safer, right? It is also a denial of service attack vector.... Same with an option that allowed you to get django to return a huge number of formsets. Huge huge. Denial of service huge.
Stop DOS’ing yourself. Sanity-check your inputs for length before you start processing them. Configure your web server to limit the length of http headers.
Same problems with
URLField.verify_exists. Easy to get django to check a
URL that takes forever. Uploaded image checking? Compressed images can become
huge. “Zip bomb”. Email checking? We had a really good regex, but you could
feed it email addresses that took forever to get parsed by the regex. There
are now much simpler regexes (which do sometimes deny a valid email
address). He showed the original regex: it took up a whole slide in a
distressingly small font...
A very important question you should ask yourself: what is the worst that could happen? What is the longest time something could take? Is calculation O(1) or is it O(n)? Or worse?
A special case: host headers. Can we trust it? No. He showed 5 different security bugs.
When dealing with security, your motto should be trust no one. Don’t trust your webserver, users, database. Check. Check. Check.
We’ll never be able to lock it down completely. And we’ll never be able to make django completely secure. We’ll keep on falling. But we have to keep on standing up and learning from our mistakes.
Learn from us!
My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.
Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):