CRLF injection found in popular Python dependency, urllib3
On April 18, 2019 a CRLF injection vulnerability was found in the popular Python library, urllib3. The urllib3 library is an HTTP client for Python that includes valuable features such as thread safety, connection pooling, client-side SSL/TLS verification, and more. It is used widely in the Python ecosystem, including within requests, another popular library. In fact, urllib3 is used by more than 500 open source libraries. If you have a Python project, it is very likely that urllib3 is in your dependency tree.
We have already added the vulnerability to our database, and if your project is being monitored by Snyk and proves to contain the vulnerable package, you will have already been notified by our routine alerts. If not, you should test your application code repository for free, to see if it is affected by the vulnerable urllib3 version.
If you find that your Python application is making use of the vulnerable library, take immediate action and upgrade to the nearest fixed version, as suggested by Snyk via your dependency tree.
CRLF injection vulnerability
CRLF refers to ‘Carriage Return, Line Feed’, which is a term used to indicate the termination of a line. A CRLF injection involves the insertion of a line termination into the application. In the case of the urllib3 vulnerability, an attacker who has control of the requesting address parameter, could manipulate an HTTP header and then attack an internal service.
The vulnerability was first discussed in a Python Bug Tracker report that discussed a similar issue in urllib2/urllib libraries (which are each part of the standard Python 2 and Python 3 libraries, respectively). Commenter Alvin Chang (username
alvinchang) noted that he was able to replicate the exploit in the urllib3 library as well.
This resulted in an issue being raised through the urllib3 GitHub repository and a fix was made available in both the
1.24.x release series and the
1.25.x release series.
The proof of concept for the vulnerability is as follows, published in the python bug tracker by user
ragdoll and adopted for the urllib3 version by
import urllib3 pool_manager = urllib3.PoolManager() host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" url = "https://" + host + ":8080/test/?test=a" try: info = pool_manager.request('GET', url).info() print(info) except Exception: pass # nc -l localhost 7777 GET /?a=1 HTTP/1.1 X-injected: header TEST: 123:8080/test/?test=a HTTP/1.1 Host: localhost:7777 Accept-Encoding: identity
In this example, the nc server displays the HTTP request with manipulated header content: X-injected:header, indicating a successful injection of the HTTP header.
Is my project vulnerable?
Are you curious to know whether your project is vulnerable? Create a free Snyk account today and check for vulnerabilities in your project. Snyk will give you a report of all the known vulnerabilities in your open source dependencies–including the urllib3 library if you are using an affected version.
It is important to understand that the urllib3 library is often an indirect dependency and you may have it installed in your project without realizing it. Some direct dependencies that use urllib3 don’t actually make use of the vulnerable parts of the library–for instance, at this time it appears that the requests library (which includes urllib3 as a dependency) is not vulnerable, but that may not be the case for all projects that depend on urllib3. Because of this, it makes sense to find out if urllib3 is in your dependency tree.
How do I protect my project?
If you find that your project uses a vulnerable version of urllib3, we recommend you upgrade urllib3 to version 1.24.3 and above. Taking this step will also protect you from a handful of other vulnerabilities that have been found in the urllib3 library. We also recommend that you inspect your code for instances of urllib2 or urllib (for Python 2 and Python 3 projects respectively). The exploits for these standard library vulnerabilities have not yet been remediated–so it is important to evaluate your individual susceptibility by reviewing your code.