CVE-2026-55555
Executive Summary
CVE-2026-55555 is a file existence oracle vulnerability residing in Dompdf, a PHP library that converts HTML to PDF. Versions 3.15 and earlier are affected. The flaw is triggered through malicious manipulation of the CSS @font-face directive. By referencing local files via the file:// protocol repeatedly, an attacker can cause PHP memory exhaustion. The observable difference in behavior—existing files lead to memory exhaustion while missing files fail fast—enables an attacker to enumerate sensitive files on the server, bypassing CHROOT restrictions. The vulnerability is fixed in Dompdf version 3.16.
Note: Dompdf is not an npm, PyPI, Go, or Ruby package; therefore no Supply Chain & Package Security section is included.
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
CVSS Breakdown & Threat Level
While the original CVSS score is listed as 0.0 (unassigned), an estimated vector based on the technical details would be:
- Attack Vector (AV): Network (exploitable remotely via HTTP requests)
- Attack Complexity (AC): Low (no specialized conditions required)
- Privileges Required (PR): None (attacker sends crafted HTML directly)
- User Interaction (UI): None (vulnerability triggers automatically on parsing)
- Scope (S): Unchanged (affects the server process)
- Confidentiality (C): Low (ability to confirm existence of arbitrary files)
- Integrity (I): None
- Availability (A): High (memory exhaustion can crash the application)
Estimated CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H (Base Score ~6.5 Medium)
The real impact depends on the attacker’s ability to repeatedly submit large HTML payloads and the configured PHP memory limit.
Deep Dive & Mechanics
Dompdf uses the @font-face CSS rule to download custom fonts. When a file:// URL is used, Dompdf attempts to read the local file. The vulnerability lies in the loop that processes these URLs:
- If the file exists: Dompdf reads it repeatedly, storing its content in memory. Each read consumes a data URI. When the total memory usage exceeds
php.ini'smemory_limit, PHP throws a fatal error and the request crashes. - If the file does not exist: Dompdf quickly fails (e.g., returns early or ignores the directive) and never accumulates significant memory.
The attacker can craft an HTML payload containing hundreds of @font-face declarations, each pointing to a guessed file path (e.g., /etc/passwd, /path/to/config.php). If the memory limit is reached only when the file exists, the application’s response (crash vs. successful PDF generation) reveals the file’s presence.
The $_dompdf_show_warnings=true setting makes the overflow more easily observable because warnings are printed before the crash.
Vulnerable vs. Patched Code
Vulnerable (version < 3.16)
In Dompdf 3.15, the FontMetrics class processes @font-face directives without limiting the number of processed file:// URLs. Each existing file is fully read and embedded, leading to unbounded memory consumption.
// Simplified vulnerable logic in FontMetrics::load_font()
foreach ($this->getAllFontFaces() as $fontFace) {
$url = $fontFace->getUrl();
if (strpos($url, 'file://') === 0) {
// Read file without any size/iteration cap
$fontData = file_get_contents($url);
$this->addFontData($fontData); // Memory grows unbounded
}
}
Patched (version 3.16)
The patched version introduces limits on the number of file:// URLs processed and adds early failure for missing files without consuming memory.
// Mitigated logic in FontMetrics::load_font() (3.16+)
$maxFontFaceCount = 50; // Arbitrary cap
$count = 0;
foreach ($this->getAllFontFaces() as $fontFace) {
if (++$count > $maxFontFaceCount) break;
$url = $fontFace->getUrl();
if (strpos($url, 'file://') === 0) {
if (!file_exists(str_replace('file://', '', $url))) {
continue; // Fast path for missing files
}
// Cap file size or use stream wrappers to limit memory
$fontData = file_get_contents($url, false, null, 0, 1024 * 1024); // 1MB limit
$this->addFontData($fontData);
}
}
Exploitation & Lab Setup
Red Team: Exploitation Steps
Prerequisites:
- Target runs Dompdf version ≤ 3.15.
- The application accepts and renders user-supplied HTML (e.g., through a web form or API).
- PHP
memory_limitis set low enough (e.g., 128M–256M) to be exhausted by repeated file reads.
Step-by-step:
- Craft a malicious HTML payload that includes many
@font-facedirectives targeting a sensitive file (e.g.,/etc/passwdfor Linux orC:\Windows\win.inifor Windows). Example (PHP code that generates payload):
<!DOCTYPE html>
<html>
<head>
<style>
@font-face { font-family: 'E1'; src: url('file:///etc/passwd'); }
@font-face { font-family: 'E2'; src: url('file:///etc/passwd'); }
<!-- repeat 500 times -->
</style>
</head>
<body><p>Test</p></body>
</html>
Send the payload to the target endpoint (e.g., POST
/convert.phpwith parameterhtml=...).Observe behavior:
- If the server returns a PDF (or a success response) → the file does not exist (or the memory limit is too high).
- If the server returns a 500 error or crashes (connection reset, timeout, or empty response) → the file exists and memory exhaustion occurred.
Refine the payload by adjusting the number of directives to exactly hit the memory limit. With
$_dompdf_show_warnings=true, the error message"Allowed memory size exhausted"confirms the oracle.Enumerate files by repeating with different paths.
Lab Setup:
- Install Dompdf 3.15 via Composer:
composer require dompdf/dompdf:3.15.* - Create a simple PHP script:
require_once 'vendor/autoload.php';
use Dompdf\Dompdf;
$html = $_POST['html'] ?? '<p>No input</p>';
$dompdf = new Dompdf();
$dompdf->set_option('isHtml5ParserEnabled', true);
$dompdf->set_option('isFontSubsettingEnabled', false);
$dompdf->loadHtml($html);
$dompdf->render();
$dompdf->stream("output.pdf");
- Set PHP memory limit to 128M.
- Run a local web server:
php -S 0.0.0.0:8080
Blue Team: Detection & Mitigation
Detection:
- Monitor server errors for repeated "Allowed memory size exhausted" messages.
- Look for unusual patterns in HTTP requests: large POST bodies containing many
@font-facedeclarations withfile://URLs. - Correlate crashes with known sensitive file paths in the request body.
Mitigation:
- Upgrade to Dompdf 3.16 or later.
- If upgrade is not possible, apply a virtual patch: WAF rule to block requests with more than X
@font-facedirectives or containingfile://in the src. - Increase PHP memory limit temporarily but this only masks the oracle.
- Disable
$_dompdf_show_warningsin production.
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to PDF generation endpoints with
htmlparameter exceeding 10KB and containing multiple@font-face { src: url('file://...') }. - Repeated occurrence of
/etc/passwd,C:\Windows\win.ini, or other common secrets in the request body.
- POST requests to PDF generation endpoints with
- Host IOCs:
- PHP error logs containing:
PHP Fatal error: Allowed memory size of XXX bytes exhaustedandDompdf\Exception\ImageException. - Apache/Nginx error logs showing
upstream timed outorconnection reset by peerfor PHP-FPM processes serving Dompdf.
- PHP error logs containing:
- File IOCs:
- Temporary files under
/tmp/or systemtempdirectory with random names, created by Dompdf during processing (though these are cleaned up quickly).
- Temporary files under
Detection Engineering
YARA Rule
rule Dompdf_FileExistenceOracle_Payload {
meta:
description = "Detects HTML payloads attempting CVE-2026-55555 file existence oracle"
author = "DevSecOps Analyst"
date = "2025-01-01"
hash = "d41d8cd98f00b204e9800998ecf8427e"
strings:
$fontface = /@font-face\s*\{[^}]*src:\s*url\(['"]?file:\/\/[^'"\)]+['"]?\)/is
$file_protocol = "file://" nocase
condition:
#fontface > 10 and #file_protocol > 10
}
Sigma Rule
title: Dompdf File Existence Oracle - Excessive file:// URLs
id: 7a5b2c11-3f4e-4d81-9c6a-1f2e3d4c5b6a
status: experimental
description: Detects HTTP POST requests with high number of file:// URIs in the body, indicating exploitation of CVE-2026-55555.
author: DevSecOps Analyst
logsource:
category: webserver
product: apache
detection:
selection:
c-uri|contains: '/convert.php' # adjust to your endpoint
cs-method: 'POST'
cs-body|contains|all:
- '@font-face'
- 'file://'
condition: selection
fields:
- c-uri
- cs-method
- cs-body
- sc-status
falsepositives:
- Legitimate use of CSS font embedding from local files (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2026-55555 Dompdf File Existence Oracle Payload"; flow:to_server,established; content:"POST"; http_method; content:"/convert.php"; http_uri; pcre:"/file:\/\/[^\"]+/i"; byte_test:1,>,10,0; threshold: type both, track by_src, count 5, seconds 60; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade Dompdf to version 3.16 or later.
- Add a WAF rule to block
file://URIs in@font-facesrc attributes. - Increase PHP memory limit to a value that makes exhaustion from this attack impractical (e.g., 512M), but note this does not fix the oracle.
Long-term:
- Limit the number of
@font-facedeclarations processed (the patch does this). - Validate and sanitize all user-supplied HTML before passing to Dompdf.
- Use
$_dompdf_show_warnings = falsein production. - Isolate Dompdf in a container with restricted file read permissions (e.g., read-only root filesystem).
- Limit the number of
Architectural:
- Do not allow direct upload of arbitrary HTML to Dompdf; instead, use a restricted template system.
- Set
chrootoption in Dompdf (if available) to limit file:// access to a dedicated directory (e.g.,/var/www/fonts/).
Valters IT - DevSecOps & Threat Intelligence
Securing your code, one CVE at a time.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.