Well, maybe that’s not the best example. But you get the point. Today, I’ll tell you how did the familiarity with some standards help me identify and contribute to fixing a bug in Django CORS headers library.
A well-known security researcher, Michał Składnikiewicz (better known as Gynvael Coldwind) once said that one way to search for vulnerabilities in software is to read the documentation. It’s quite common for developers to skip certain requirements and silently assume that the end user won’t do anything stupid. Before we begin, I must admit, that if it wasn’t for an excellent article written by Sekurak team on the way CORS works, I would still be unaware of the issue. Also, I strongly suggest going through my previous article about CORS headers or Mozilla’s guide to CORS since the issue is quite complex and I am going to assume that you know the basics.
Anyway, the RFC 6454 says that an Origin is something consisting of three elements: scheme, host, and port (which could be given implicitly, ie. it’s assumed that for http://example.com/ port is 80). The reason to require the entire host, not only top-level domain is to enable web developers to have better isolation of their architecture elements. Similarly, the goal of requiring scheme is to let developers take full advantage of TLS encryption.
The library I used did not honor this requirement and ignored the scheme. This meant that someone who wanted to secure their infrastructure by requiring connections to https could not achieve this with that particular library (at least not by enumerating full origins, regular expressions could still solve this). I’ve decided to open an issue and wait for a response which came as a pleasant surprise.
Working on a library turned out to be an interesting experience, quite different from what I knew to that point. This was the first time I touched the middleware, needed to ensure that a programmer using the library will comply with my requirements and maintain some decent standard of code. Luckily, with some help from the author and other people, I managed to deliver some intermediate version of what I wanted to achieve: allowing a user to restrict usage of the scheme while maintaining backward compatibility with previous versions, where the scheme was not required. My changes were merged in PR 388 and later improved by the maintainer in PR-397. This strategy paid off:
When you go to PyPI repository and read through the library's documentation, you can see reference to proper RFC document and updated examples.
3 reasons to do care about RFCs
RFCs are definitely not the most breathtaking things to read (although I might argue they’re still better than Lord of the Rings since at least moving from page to page brings in something new), but they are important. If you are creating a library a solid understanding and familiarity with widely accepted standards is a must. Otherwise, you might put your users in jeopardy. This case brings another few lessons about open source.
First, that being open source does not equal to being secure. This problem existed in the library for quite a long time and negligence in checking how it should work by many people who decided to use it shows that “many eyes looking at code” is sometimes not enough.
Second, that scrutiny from someone who knows something more is possible. It’s enough when one person knows something more to start improvement. If this library was closed-source the bug could stay there and I would be stuck using insecure solution kindly asking someone to do something about it.
And last, while open source is very ambivalent when it comes to security, it brings in countless opportunities to learn something new. And this is an indisputable benefit. Not only was I able to find some bug, but also learn something while fixing it and help some people all around the world to make their projects safer. I must say this is an extremely rewarding feeling.
What should I say more? The knowledge that is both wide and deep is one thing that determines a true hacker. Willingness to share it is the second one and taking actual action to improve something is the last one. This experience was the most hacker-like in my life. I hope it was not the last one of this kind.
So, learn standards well, look out for bugs and fix them and, to quote Richard Stallman: