The open-source PDF rendering library Poppler is widely used by Linux distributions and software like Okular and Evince. In August 2022, security researchers discovered a high-impact bug: CVE-2022-38349. This flaw makes it possible for a specially-crafted PDF file to crash Poppler-powered applications—potentially allowing attackers to perform a Denial of Service (DoS) attack.

Let’s break down what happened, show you the key code logic, and demonstrate how an attacker could exploit this bug.

What is Poppler & Why Does It Matter?

Poppler is the engine behind many PDF viewers and tools on Linux. Applications trust Poppler to parse, modify, and render PDFs. This means that any vulnerability in Poppler can have a wide impact, especially as Poppler often runs with user privileges.

The Heart of the Bug: What is CVE-2022-38349?

CVE-2022-38349 is a bug triggered by missing input checks in Poppler's code. Specifically, the function PDFDoc::replacePageDict in PDFDoc.cc doesn’t make sure that the PDF data it’s going to process is actually a stream—a fundamental PDF object type used to hold things like images, file attachments, etc.

If the wrong kind of object is handled without this check, it triggers a failed assertion in Poppler's codebase (in Object.h). That means Poppler will abruptly exit, crashing the application.

Key Point

This is a Denial of Service vulnerability: it won’t let an attacker run code on your computer, but it will take down the application you’re trying to use.

What Part of the Code Is Involved?

The bug lives in how Poppler handles page dictionaries (metadata about pages) inside PDFs. Here’s a simplified look at the key function:

// PDFDoc.cc
bool PDFDoc::replacePageDict(int page, Object *pageDict) {
    // ... some code ...
    Object pageStream = pageDict->lookup("EmbeddedFile");
    // --- PROBLEM: There is no check if pageStream is actually a stream ---
    // ... tries to save the embedded file, expects pageStream to be a stream ...
    // Triggers assertion in Object.h if it isn't.
    // ... more code ...
}

The assertion that gets triggered sits in Object.h

// Object.h
void Object::streamCheck() {
    assert(type == objStream); // This assertion fails if type isn't a stream
    // ...
}

So, if pageStream is, say, an integer or dictionary and not a stream, Poppler crashes.

Create a Malicious PDF:

The attacker crafts a PDF where the /EmbeddedFile entry in a page dictionary is something other than a stream—maybe a simple dictionary.

Send the PDF:

The attacker sends or tricks the victim into opening or processing the PDF with a Poppler-based application. This could be on a server, a desktop, or any automation using Poppler's tools.

Trigger Crash:

When Poppler’s tools (or a PDF viewer) try to process the page dictionary and save the embedded file, the missing check causes a failed assertion, crashing the process.

Example Malicious PDF Snippet

Below is simplified pseudocode, not a full PDF, showing how the attack PDF might define the reference wrong:

%PDF-1.5
1  obj
<< /Type /Catalog /Pages 2  R >>
endobj
2  obj
<< /Kids [3  R] /Count 1 /Type /Pages >>
endobj
3  obj
<< /Type /Page 
   /EmbeddedFile 4  R    % Should be a stream, but it's a dictionary
>>
endobj
4  obj
<< /Type /NotAStream >>
endobj

In this minimal PDF, the /EmbeddedFile key refers to object 4 R, which is a dictionary, not a stream. This will crash Poppler 22.08. when it tries to process or save the attachment.

Real-World Impact

- Crash desktop apps: Okular, Evince, Xpdf, and others using Poppler to render or modify PDFs could be crashed by a single malicious file.
- Disrupt automated systems: Servers processing PDFs (indexing, previewing, converting) could be taken down.
- Denial of Service as an attack vector: While attackers can’t run code or steal data with this bug, they can reliably crash processes.

Was It Fixed?

Yes. The Poppler team fixed this by adding a check to ensure that the object being saved as a stream is actually a stream.

Reference commit:
- Fix for CVE-2022-38349 in Poppler

Security advisory/announcement:
- freedesktop.org security mailing list
- CVE entry at NIST NVD

Defensive Actions

- Update Poppler — If you use Poppler or any application using it, upgrade to version 22.08. or higher where this bug is fixed.

Conclusion

CVE-2022-38349 is a classic example of why type and sanity checks are vital in software that processes untrusted data. Even just a missing type check on a PDF dictionary can allow a remote attacker to crash crucial desktop software and even backend PDF processing systems.

References

- Official CVE-2022-38349 entry (NVD)
- Poppler GitLab: Commit fixing CVE-2022-38349
- Red Hat Security Blog on CVE-2022-38349
- Debian Security Bug report for CVE-2022-38349

Timeline

Published on: 08/22/2023 19:16:00 UTC
Last modified on: 08/28/2023 18:29:00 UTC