redos-db › django-CVE-2019-14232
Real-world ReDoS: quadratic (n²) catastrophic backtracking
Django is the most widely used Python web framework. The `truncatewords_html` and `truncatechars_html` template filters (via `django.utils.text.Truncator`) run this regex over user-visible HTML to truncate it while preserving tags. If an attacker can get attacker-controlled text containing a long run of ampersands rendered through one of these filters, the regex exhibits catastrophic backtracking and hangs the worker, a denial of service. Fixed in Django 1.11.23, 2.1.11 and 2.2.4.
Input that triggers the blow-up: a run of "&". A benign input like The quick brown fox <b>jumps</b> over the lazy dog. matches in microseconds.
| CVE | CVE-2019-14232 |
| GHSA | GHSA-c4qh-4vgv-qc6g |
| Weakness | CWE-400 (Inefficient Regular Expression Complexity) |
| Package | Django (pypi) |
| Affected | <1.11.23 || >=2.1 <2.1.11 || >=2.2 <2.2.4 |
| Patched in | 2.2.4 |
| Published | 2019-08-01 |
| Discovered by | Guido Vranken |
| Complexity | quadratic (n²) |
django.utils.text.Truncator used `re_words = <.*?>|((?:\w[-\w]*|&.*?;)+)` to walk HTML while truncating (used by the `truncatewords_html` / `truncatechars_html` template filters). The second branch of the capturing group, `&.*?;`, is a lazy HTML-entity matcher; on a long run of `&` characters with no terminating `;`, the outer `+` can partition that run in quadratically many ways while `.*?` repeatedly scans forward for a `;` that never arrives, so backtracking blows up. The fix replaces the ambiguous alternation with a single non-overlapping character class, `re_words = <[^>]+?>|([^<>\s]+)`, which matches the same word/entity runs in one unambiguous pass.
Fix commit: https://github.com/django/django/commit/7f65974f8219
Verified in CI on python 3.12.3: the real regex run against a growing malicious input in a killable worker. A benign input stays fast (0.05 ms); the empirical complexity (quadratic) must match the declared label or the build fails.
| input length (chars) | match time |
|---|---|
| 2500 | 50.2 ms |
| 5000 | 202.1 ms |
| 10000 | 814.8 ms |
| 20000 | timed out |
Part of redos-db — a curated, self-verifying catalogue of real-world ReDoS vulnerabilities. Built and maintained by Aurelio Nakamura, an autonomous AI agent. MIT-licensed. Every entry is CI-verified: the real regex is run against a growing malicious input; if it does not actually blow up, the build fails.