CVE-2026-59941
Executive Summary
CVE-2026-59941 is a critical resource exhaustion vulnerability in the Dompdf HTML‑to‑PDF converter for PHP. Affecting versions 3.15 and prior, the flaw allows an unauthenticated attacker to trigger massive memory amplification by supplying a crafted BMP image whose header declares an arbitrarily large pixel canvas (e.g., 6000×6000) without any bounds checking. When Dompdf processes such an image, it calls imagecreatetruecolor($width, $height) with the attacker‑supplied dimensions, causing PHP to allocate a full pixel canvas proportional to the declared size. The BMP can be inlined as a data:image/bmp;base64,… URI inside attacker‑controlled HTML, requiring no file upload or remote fetch. A single 169‑byte request can drive memory consumption from ~34 MB (benign) to ~412 MB – a ~12× amplification. This can be repeated indefinitely, leading to denial of service by exhausting server memory and CPU resources.
The vulnerability has been fixed in Dompdf version 3.16 by adding validation of BMP dimensions before canvas allocation.
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
Although a CVSS vector was not officially published, the impact aligns with an AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H profile:
- Attack Vector (AV): Network – the payload is delivered via HTTP request.
- Attack Complexity (AC): Low – no special conditions required.
- Privileges Required (PR): None – unauthenticated.
- User Interaction (UI): None – automated request.
- Scope (S): Unchanged.
- Confidentiality (C): None.
- Integrity (I): None.
- Availability (A): High – memory/CPU exhaustion leads to denial of service.
With no official CVSS, the Temporal Score is not applicable, and Environmental Score depends on PHP memory limits. In shared hosting environments, this can crash services.
Threat Level: High (due to low complexity, no auth, and significant resource amplification).
Deep Dive & Mechanics
The core issue lies in the BMP image handling within Dompdf’s image processing pipeline. When Dompdf encounters a BMP (e.g., via <img src="data:image/bmp;base64,...">), it uses PHP’s GD library to convert the BMP to a PNG suitable for PDF embedding. The conversion logic reads only the BMP header to obtain width and height, then calls:
$im = imagecreatetruecolor($width, $height);
No validation is performed to ensure that the product width × height is within a reasonable bound (e.g., total pixel count less than some maximum). An attacker can craft a 58‑byte BMP whose header declares dimensions such as 6000×6000 (36 million pixels). PHP’s GD library will attempt to allocate memory for 36 million pixels (each pixel potentially several bytes). The resulting memory footprint far exceeds the size of the original input.
Attack Flow:
- Attacker creates an HTML document containing:
<img src="data:image/bmp;base64,Qk1...">where the base64 decodes to a minimal BMP header with inflated dimensions. - The HTML is sent in a single HTTP POST/GET request to a Dompdf endpoint (e.g., a web form that converts HTML to PDF).
- Dompdf parses the HTML, encounters the BMP data URI, decodes it, reads header width/height (e.g., 6000×6000), and calls
imagecreatetruecolor(6000, 6000). - PHP allocates a canvas of ~144 MB (assuming 4 bytes per pixel) plus overhead, triggering a memory spike to >400 MB RSS.
Compared to a benign request (no BMP or properly sized image), the memory amplification factor is roughly 12×.
Because the BMP is inlined as a data URI, no file upload or external resource is needed. The attack is stateless and fully automated.
Vulnerable vs. Patched Code
Vulnerable Code (Dompdf ≤ 3.15)
In the image.php or similar BMP handler, the vulnerable pattern is:
// Read BMP header
$width = unpack('V', fread($stream, 4))[1];
$height = unpack('V', fread($stream, 4))[1];
// No bounding check
$im = imagecreatetruecolor($width, $height);
The dimensions are used directly without any sanity check.
Patched Code (Dompdf 3.16)
The fix introduces validation to reject BMP images with excessive dimensions:
// Read BMP header
$width = unpack('V', fread($stream, 4))[1];
$height = unpack('V', fread($stream, 4))[1];
// Reject if dimensions exceed reasonable limits (e.g., max 2000x2000)
if ($width > 2000 || $height > 2000) {
throw new \Exception('BMP dimensions too large');
}
$im = imagecreatetruecolor(max(1, $width), max(1, $height));
The exact threshold may vary; the important change is that the dimension product is bounded before resource allocation.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites
- A Dompdf instance (version ≤ 3.15) exposed to HTTP (e.g., a web application that renders user‑submitted HTML to PDF).
- PHP GD extension enabled.
Payload Crafting
- Create a minimal BMP header with inflated dimensions (e.g., 6000×6000). A simple 58‑byte BMP can be constructed:
- Header:
\x42\x4d(magic), file size, reserved, offset (54), header size (40), width (6000), height (6000), planes (1), bpp (24), compression (0), etc.
- Header:
- Base64‑encode the raw BMP bytes.
- Embed in HTML:
<html> <body> <img src="data:image/bmp;base64,Qk1...BASE64_DATA...=" /> </body> </html> - Send a POST request to the Dompdf endpoint (e.g.,
POST /convert.php) with the HTML as form data.
Expected Results
- Memory consumption jumps from ~34 MB to ~412 MB per request.
- Repeated requests (e.g., 50 concurrent) exhaust available memory, causing PHP worker crashes and potential denial of service.
Automation (Python script)
import requests
bmp_payload = "<BASE64_BMP>" # pre‑generated
html = f"""<img src="data:image/bmp;base64,{bmp_payload}">"""
url = "https://target.com/convert.php"
while True:
requests.post(url, data={"html": html})
Blue Team (Detection & Mitigation)
Detection
- Monitor memory usage of PHP workers. Sudden spikes from ~30 MB to >200 MB per request indicate exploitation.
- Log analysis: large
imagecreatetruecolorcalls can be identified via slow query log or Xdebug traces if enabled. - Network traffic: base64‑encoded BMP data URIs with unusually large decoded size relative to payload.
Mitigation
- Immediate: Upgrade Dompdf to version 3.16 or later.
- Workaround: If upgrading not possible, restrict maximum POST size and disable data URI handling for images, or add a custom filter that rejects BMP data URIs.
- Resource limits: Set PHP
memory_limitto a safe value. While this prevents full exhaustion, it still degrades performance. Useulimitand process isolation (e.g., separate PHP-FPM pool for Dompdf).
Indicators of Compromise (IOCs)
Network
- HTTP requests containing
data:image/bmp;base64,followed by a long base64 string. - Unusually large Content-Length for a simple HTML document, especially combined with a PDF response (indicating conversion occurred).
- HTTP requests containing
Host/Process
- PHP process memory consumption exceeding 400 MB RSS from a single request.
- Core dumps or OOM killer logs referencing PHP.
- Slow response times and high CPU usage on the web server.
Application Logs
- GD errors like
imagecreatetruecolor(): Memory exhaustedorOut of memory. - Repeated timeouts for the same endpoint.
- GD errors like
Detection Engineering
YARA Rule
rule dompdf_bmp_memory_amplification {
meta:
description = "Detects crafted BMP images with inflated dimensions used for CVE-2026-59941"
author = "Valters IT / DevSecOps Team"
date = "2026-01-01"
reference = "CVE-2026-59941"
strings:
$bmp_magic = { 42 4D } // "BM"
$base64_data = /data:image\/bmp;base64,[A-Za-z0-9+/=]+/ nocase
condition:
#bmp_magic > 0 and #base64_data > 0
}
Sigma Rule
title: Dompdf BMP Resource Exhaustion Attempt
id: dompdf_bmp_amplification
description: Detects HTTP requests containing BMP data URIs with potentially inflated dimensions.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-59941
status: experimental
author: Valters IT
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
request_body|contains|all:
- 'data:image/bmp;base64,'
- '<img'
condition: selection
fields:
- src_ip
- user_agent
- request_body_length
falsepositives:
- Legitimate BMP images used by known applications
level: high
Suricata Rule
alert http any any -> any any (msg:"Dompdf BMP Memory Amplification Attempt (CVE-2026-59941)"; flow:to_server; content:"data:image/bmp;base64"; http_client_body; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Primary:
Upgrade to Dompdf version 3.16 or later. The fix enforces dimension limits during BMP processing.
Secondary (if upgrade not immediate):
- PHP Memory Limit: Set
memory_limit = 128Minphp.inito constrain each request, but memory exhaustion will still occur. - Disable data URIs: If not required, strip
data:URIs from input HTML using a content filter before passing to Dompdf. - Input Validation: Add a custom pre‑processor that parses HTML and rejects
<img>tags withsrccontainingdata:image/bmp. - Rate Limiting: Apply strict rate limiting on PDF conversion endpoints to reduce impact of repeated attacks.
- Web Application Firewall (WAF): Deploy a rule to block requests containing
data:image/bmp;base64in POST bodies.
Long‑term:
Implement resource quotas per worker process and consider running Dompdf in a sandboxed environment (e.g., container with limited memory).
© 2026 Valters IT – DevSecOps & Cyber Threat Intelligence Division
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.