If you use TCPDF to generate PDFs from HTML in your PHP projects, there’s a new vulnerability you need to know about: CVE-2024-22640. This vulnerability makes older versions—specifically TCPDF 6.6.5 and below—susceptible to a type of Denial of Service attack called ReDoS (Regular Expression Denial of Service). The problem boils down to an unsafe preg_match pattern in how TCPDF parses color values inside HTML.

In this long read, I’ll explain the issue, show you the vulnerable code, how an attacker can exploit it, and what you need to do to keep your projects safe.

What is TCPDF and Why Does This Matter?

TCPDF is one of the most popular PHP libraries for creating PDF documents straight from HTML. Since it’s widely used in web applications, any security hole in TCPDF has major consequences. CVE-2024-22640 is especially worrying because ReDoS is easy to trigger and very hard to detect before it’s too late.

The Vulnerability Explained

In versions of TCPDF up to and including 6.6.5, there’s a function responsible for parsing color codes from HTML inputs. The parser uses a regular expression to check if a value like rgb(255, , ) or #ff000 is a valid color.

Here’s the problem: the regex is complicated and implemented in a way that—when fed a specially crafted string—can take a very long time to process. That’s because of the way preg_match() works in PHP. With heavy backtracking, a small input can keep your PHP process busy, maxing out CPU and making your app unresponsive.

If an attacker feeds untrusted HTML containing a malicious color string to TCPDF, your server can get stuck, effectively creating a DoS situation.

Here’s a simplified version of the problematic code you’ll find in tcpdf.php

if (preg_match('/^rgb[a]?\(\s*(\d+\s*,\s*){2,3}\d+\s*\)$/i', $color)) {
  // process color...
}

This regex is designed to match color codes like rgb(123, 45, 67) and rgba(1,2,3,.5). But its greedy quantifiers and nested groups make it vulnerable to catastrophic backtracking.

How The Exploit Works

Attackers simply craft a color string that the regex engine will struggle to parse. For example, repeating certain patterns can cause preg_match to hang.

Malicious Input Example

$color = "rgb(" . str_repeat('1,', 10000) . "1)";
tcpdf_some_function($color);

In practice, that might look like an HTML snippet inside user-supplied input

<span style="color: rgb(1,1,1,1,1,1,...10000 times...)">Hello</span>

When TCPDF tries to parse the color value, it enters a backtracking storm, and your server's PHP process grinds to a halt.

Real-World Impact

Imagine a public PDF generation feature—for invoices, emails, or reports. If attackers can control some or all of the HTML (directly or via data injection), they could take down your service at will, using just a single carefully-crafted request!

This doesn’t just block one user; it can slow or stall your entire web server if enough requests come in.

Original References

- CVE Details for CVE-2024-22640
- GitHub Issue and Patch (official, with fix)
- Release Notes for TCPDF

How to Fix It

Update to TCPDF 6.6.6 or later.
The regular expression has been fixed to eliminate catastrophic backtracking. Upgrading is the only safe choice.

If you can’t update immediately:

After the fix, the regex might look like this (simplified)

if (preg_match('/^rgba?\(\s*(\d{1,3}\s*,\s*){2,3}\d{1,3}\s*\)$/i', $color)) {
  // Now safe.
}

Or, better yet, non-regex-based color parsing.

Conclusion

CVE-2024-22640 shows how even a tiny mistake in regex can have big consequences when untrusted input is in play. Check your composer files, upgrade TCPDF, and be careful with what you let users plug into your PDF generator.

Resources

- TCPDF on GitHub
- TCPDF Official Site
- Understanding Regular Expression Denial of Service (ReDoS) (OWASP)

Timeline

Published on: 04/19/2024 16:15:09 UTC
Last modified on: 07/03/2024 01:47:19 UTC