In February 2024, a new vulnerability was disclosed in the popular Python web framework Django: CVE-2024-27351. This bug affects the django.utils.text.Truncator.words() method (when used with html=True) and the truncatewords_html template filter, potentially allowing attackers to launch a Denial-of-Service (DoS) attack using a maliciously crafted string.
5. before 5..3
It's important to note: This bug is a result of an incomplete fix for two previous vulnerabilities—CVE-2019-14232 and CVE-2023-43665.
What is CVE-2024-27351?
CVE-2024-27351 is a security issue where certain regular expressions inside Django’s HTML truncation features can be abused to cause a Denial-of-Service (DoS). This happens when an attacker tricks the app into running a super-slow regex match on a specially crafted malicious string.
In plain English: You can freeze some Django websites (make them unresponsive) just by sending or storing certain nasty text.
The Truncator.words() utility, when used like Truncator(some_html).words(limit, html=True)
- The {% truncatewords_html %} template filter (used in templates to safely shorten HTML content by word count)
Both features aim to safely clip HTML fragments without breaking tags or leaving malformed HTML.
How Does the Exploit Work?
The core problem is a regular expression (regex) that’s supposed to help figure out where tags and words are in the HTML. With a complex enough string—especially if it has lots of nested or misleading HTML tags—the regex can be forced to “backtrack” for a very long time.
Here is a simplified example
from django.utils.text import Truncator
# Malicious, deeply nested string (simplified version)
evil_input = "<b" + " " * 100000 + "<"
# This function call will hang or take a very long time
Truncator(evil_input).words(10, html=True)
If a user controls any content that passes through this filter (for example, a blog post, comment, or form input), they could crash your server or web workers by submitting carefully crafted input. Remember, with WSGI or ASGI, a single blocked worker can hold up further requests, making this a real threat.
Why is This Dangerous?
- Anyone can send malicious input: Any page that displays user data using the affected methods can be targeted.
DoS potential: Attackers can freeze your site with a single POST or GET request.
- WAF/bot protection won’t help much: The attack uses plain HTML syntax, not weird code.
Let’s see a more exact exploit. Here’s how you could use the Django shell to demonstrate
from django.utils.text import Truncator
import time
# "evil_html" makes the regex run super slow
evil_html = (
"<b>" +
("<i>" * 100) +
"text" +
("</i>" * 100) +
"</b>"
)
start = time.time()
# Trigger the slow regex
Truncator(evil_html).words(1, html=True)
print("Time elapsed:", time.time() - start)
If you increase the number of <i> tags, you’ll see the time climb dramatically, potentially eating up all your server threads.
Links to Original References
- Django Security Advisory: https://docs.djangoproject.com/en/dev/releases/security/
- CVE Details: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-27351
- Patch in Code: Django GitHub Commit (example)
Conclusion
CVE-2024-27351 is a clear example of a regular expression gone rogue in web frameworks. Even after two rounds of fixes, clever attackers found a new way to break Django’s HTML truncation logic.
If you run a public Django site, especially one where users can post HTML content, you need to patch now! Otherwise, you’re risking potentially simple DoS attacks that can take your site offline.
Stay safe, and keep your dependencies up-to-date!
*Exclusive content by AI, April 2024. For any questions about this vulnerability, see the official Django announcement.*
Timeline
Published on: 03/15/2024 20:15:09 UTC
Last modified on: 07/03/2024 01:50:33 UTC