CVE-2026-59941
Dompdf: Uncontrolled resource consumption based on declared BMP dimensions
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
6.3
Dompdf: Uncontrolled resource consumption based on declared BMP dimensions
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
- Record
CVE-2026-59941- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-02
EUVDEUVD-2026-50061
6.3
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
- Record
EUVD-2026-50061- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-8hg6-c449-896m
6.3
Dompdf: Uncontrolled resource consumption based on declared BMP dimensions
Summary
dompdf accepts a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas.
A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. It was demonstrated that a 169-byte request drove dompdf to render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated.
Details
Root cause
The image is processed based on declared dimensions and type alone — no pixel budget:
// src/Image/Cache.php:131-134
list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $options->getHttpContext());
if (($width && $height && in_array($type, ["gif","png","jpeg","bmp","svg","webp"], true)) === false) {
throw new ImageException("Image type unknown", E_WARNING);
}
For BMPs that getimagesize() does not fully parse, dompdf trusts the raw header fields:
// src/Helpers.php:833-837
if (substr($data, 0, 2) === "BM") {
$meta = unpack("vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight", $data);
$width = (int) $meta["width"];
$height = (int) $meta["height"];
$type = "bmp";
}
At conversion time the canvas is allocated from those declared dimensions, before any check that enough pixel data exists:
// src/Helpers.php:868-869 — native decoder is tried FIRST on PHP >= 7.2
if (function_exists("imagecreatefrombmp") && ($im = imagecreatefrombmp($filename)) !== false) {
return $im;
}
// src/Helpers.php:940 — hand-rolled fallback
$im = imagecreatetruecolor($meta['width'], $meta['height']);
There is no maximum width/height or maximum total-pixel guard anywhere on this path.
Source-to-sink
- Attacker HTML reaches
Dompdf::loadHtml()with<img src="data:image/bmp;base64,…">(or any BMPsrc). Dompdf::render()decorates frames;Frame\Factorymarks<img>as an image;FrameDecorator\ImagecallsImage\Cache::resolve_url().Image\Cache::resolve_url()accepts the BMP on declared dimensions/type (src/Image/Cache.php:131-134).- During render,
Adapter\CPDF::image()identifies the BMP and calls_convert_to_png()(src/Adapter/CPDF.php:593). _convert_to_png()invokesHelpers::imagecreatefrombmp(), which allocates the full canvas — via the nativeimagecreatefrombmp()on PHP ≥ 7.2, or the hand-rolledimagecreatetruecolor()fallback otherwise.
PoC
erified against dompdf @ a6ddc4f on PHP 8.3.6 with GD enabled.
The crafted BMP is 58 bytes: a 14-byte file header + 40-byte BITMAPINFOHEADER declaring the target width/height at 24bpp + 4 padding bytes. Inlined as a data URI, the full attacker payload is 169 bytes:
<html><body><img src="data:image/bmp;base64,Qk06AAAAAAAAADYAAAAoAAAAcBcAAHAXAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" style="width:1px;height:1px"></body></html>
(The base64 above decodes to a 58-byte BMP declaring 6000×6000. The CSS width:1px;height:1px does not help the defender — the intrinsic decode happens regardless.)
1 — Direct conversion
native imagecreatefrombmp exists: yes
dompdf_getimagesize => 6000x6000 type=bmp
imagecreatefrombmp => GdImage 6000x6000 (allocated from a 58-byte file)
Maximum resident set size: 160 MB (10x10 control: 24 MB)
php_peak (PHP-managed): 0.8 MB <-- GD memory is native; PHP memory_limit does NOT cap it
The PHP-managed peak is under 1 MB while RSS is 160 MB: the canvas lives in GD's native allocator, so…
- Record
GHSA-8hg6-c449-896m- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-02
NVD
6.3
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
- Record
CVE-2026-59941- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
OSV
6.3
Dompdf: Uncontrolled resource consumption based on declared BMP dimensions
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
- Record
CVE-2026-59941- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-59941
7.5
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
- Record
DEBIAN-CVE-2026-59941- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
Show 5 moreShow less
OSVGHSA-8hg6-c449-896m
6.3
Dompdf: Uncontrolled resource consumption based on declared BMP dimensions
Summary
dompdf accepts a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas.
A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. It was demonstrated that a 169-byte request drove dompdf to render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated.
Details
Root cause
The image is processed based on declared dimensions and type alone — no pixel budget:
// src/Image/Cache.php:131-134
list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $options->getHttpContext());
if (($width && $height && in_array($type, ["gif","png","jpeg","bmp","svg","webp"], true)) === false) {
throw new ImageException("Image type unknown", E_WARNING);
}
For BMPs that getimagesize() does not fully parse, dompdf trusts the raw header fields:
// src/Helpers.php:833-837
if (substr($data, 0, 2) === "BM") {
$meta = unpack("vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight", $data);
$width = (int) $meta["width"];
$height = (int) $meta["height"];
$type = "bmp";
}
At conversion time the canvas is allocated from those declared dimensions, before any check that enough pixel data exists:
// src/Helpers.php:868-869 — native decoder is tried FIRST on PHP >= 7.2
if (function_exists("imagecreatefrombmp") && ($im = imagecreatefrombmp($filename)) !== false) {
return $im;
}
// src/Helpers.php:940 — hand-rolled fallback
$im = imagecreatetruecolor($meta['width'], $meta['height']);
There is no maximum width/height or maximum total-pixel guard anywhere on this path.
Source-to-sink
- Attacker HTML reaches
Dompdf::loadHtml()with<img src="data:image/bmp;base64,…">(or any BMPsrc). Dompdf::render()decorates frames;Frame\Factorymarks<img>as an image;FrameDecorator\ImagecallsImage\Cache::resolve_url().Image\Cache::resolve_url()accepts the BMP on declared dimensions/type (src/Image/Cache.php:131-134).- During render,
Adapter\CPDF::image()identifies the BMP and calls_convert_to_png()(src/Adapter/CPDF.php:593). _convert_to_png()invokesHelpers::imagecreatefrombmp(), which allocates the full canvas — via the nativeimagecreatefrombmp()on PHP ≥ 7.2, or the hand-rolledimagecreatetruecolor()fallback otherwise.
PoC
erified against dompdf @ a6ddc4f on PHP 8.3.6 with GD enabled.
The crafted BMP is 58 bytes: a 14-byte file header + 40-byte BITMAPINFOHEADER declaring the target width/height at 24bpp + 4 padding bytes. Inlined as a data URI, the full attacker payload is 169 bytes:
<html><body><img src="data:image/bmp;base64,Qk06AAAAAAAAADYAAAAoAAAAcBcAAHAXAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" style="width:1px;height:1px"></body></html>
(The base64 above decodes to a 58-byte BMP declaring 6000×6000. The CSS width:1px;height:1px does not help the defender — the intrinsic decode happens regardless.)
1 — Direct conversion
native imagecreatefrombmp exists: yes
dompdf_getimagesize => 6000x6000 type=bmp
imagecreatefrombmp => GdImage 6000x6000 (allocated from a 58-byte file)
Maximum resident set size: 160 MB (10x10 control: 24 MB)
php_peak (PHP-managed): 0.8 MB <-- GD memory is native; PHP memory_limit does NOT cap it
The PHP-managed peak is under 1 MB while RSS is 160 MB: the canvas lives in GD's native allocator, so…
- Record
GHSA-8hg6-c449-896m- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-59941
6.3
Dompdf is an HTML to PDF converter for PHP. Versions 3.15 and prior accept a BMP image and generates a PDF-compatible PNG based only on its declared header dimensions and never bounds width × height before the image is converted through GD. A 58-byte BMP whose header declares e.g. 6000×6000 is accepted and later drives imagecreatetruecolor($width, $height) (and PHP's native BMP decoder) to allocate the full pixel canvas. A payload can fit in a single HTTP request: the BMP can be inlined as a data:image/bmp;base64,… URI inside attacker-controlled HTML, so no upload, no remote fetch, and no chroot-reachable file is required. I measured a 169-byte request driving a dompdf render to ~412 MB peak RSS and ~4.8 s of CPU/wall time, versus ~34 MB for an identically-sized benign request — roughly a 12× memory amplification per request, repeatable and unauthenticated. This issue has been fixed in version 3.16.
- Record
UBUNTU-CVE-2026-59941- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVCLSA-2026-1786371522 No score
TuxCare security update for dompdf/dompdf (5 CVEs)
TuxCare rebuilt dompdf/dompdf to address 5 CVEs. Fixed in 3.1.0-p1+tuxcare.
- Record
CLSA-2026-1786371522- Updated
- 2026-11-02
OSVCLSA-2026-1787223739 No score
TuxCare security update for dompdf/dompdf (6 CVEs)
TuxCare rebuilt dompdf/dompdf to address 6 CVEs. Fixed in 1.2.2-p2+tuxcare.
- Record
CLSA-2026-1787223739- Updated
- 2026-11-02
OSVCLSA-2026-1787828763 No score
TuxCare security update for dompdf/dompdf (6 CVEs)
TuxCare rebuilt dompdf/dompdf to address 6 CVEs. Fixed in 0.8.6-p2+tuxcare.
- Record
CLSA-2026-1787828763- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
dompdf/dompdfPackagist |
before 3.1.6 | 3.1.6 |
dompdf/dompdfTuxCare:Packagist From an advisory covering 5 CVEs |
3.1.0 up to 3.1.0-p1+tuxcare | 3.1.0-p1+tuxcare |
dompdf/dompdfTuxCare:Packagist From an advisory covering 6 CVEs |
v1.2.2 up to 1.2.2-p2+tuxcare, plus listed versions 1.2.2-p1+tuxcare |
1.2.2-p2+tuxcare |
dompdf/dompdfTuxCare:Packagist From an advisory covering 6 CVEs |
0.8.6 up to 0.8.6-p2+tuxcare, plus listed versions 0.8.6-p1+tuxcare |
0.8.6-p2+tuxcare |
php-dompdfDebian:12 |
All versions, plus listed versions 2.0.3+dfsg-12.0.3+dfsg-1+deb12u12.0.3+dfsg-22.0.3+dfsg-32.0.3+dfsg-4 Show 10 moreShow less2.0.4+dfsg-12.0.4+dfsg-22.0.7+dfsg-13.0.0+dfsg-13.0.0+dfsg-23.0.1+dfsg-13.0.2+dfsg-13.1.0+dfsg-13.1.4+dfsg-13.1.4+dfsg-2 |
None known |
dompdf/dompdfPackagist |
before 3.1.6, plus listed versions v0.6.0v0.6.1v0.6.2v0.7.0v0.7.0-beta Show 34 moreShow lessv0.7.0-beta2v0.7.0-beta3v0.8.0v0.8.1v0.8.2v0.8.3v0.8.4v0.8.5v0.8.6v1.0.0v1.0.1v1.0.2v1.1.0v1.1.1v1.2.0v1.2.1v1.2.2v2.0.0v2.0.1v2.0.2v2.0.3v2.0.4v2.0.5v2.0.7v2.0.8v3.0.0v3.0.1v3.0.2v3.1.0v3.1.1v3.1.2v3.1.3v3.1.4v3.1.5 |
3.1.6 |
php-dompdfUbuntu:Pro:16.04:LTS |
All versions, plus listed versions 0.6.1+dfsg-20.6.1+dfsg-2build10.6.1+dfsg-2ubuntu10.6.1+dfsg-2ubuntu1+esm1 |
None known |
php-dompdfUbuntu:Pro:18.04:LTS |
All versions, plus listed versions 0.6.2+dfsg-30.6.2+dfsg-3ubuntu0.18.04.1~esm1 |
None known |
php-dompdfUbuntu:20.04:LTS |
All versions, plus listed versions 0.6.2+dfsg-30.6.2+dfsg-3ubuntu0.20.04.1 |
None known |
php-dompdfUbuntu:22.04:LTS |
All versions, plus listed versions 0.6.2+dfsg-3.10.6.2+dfsg-3.1ubuntu0.1 |
None known |
Public exploits
Links only. Every CVE stores no exploit code.
| Source | Link | Date |
|---|---|---|
| PoC in GitHub | far00t01/CVE-2026-59941 | 2026-08-02 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-59941 is a medium vulnerability (CVSS 6.3) in Dompdf, published July 22, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.64%, the 51st percentile. Fixed in dompdf/dompdf 3.1.6.
References
github.com/dompdf/dompdf/security/advisories/GHSA-8hg6-c449-896m
github.com/dompdf/dompdf/commit/7c65e7bbeccf146b2409740405af73949ad129d0
github.com/dompdf/dompdf/releases/tag/v3.1.6
github.com/advisories/GHSA-8hg6-c449-896m
github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59941.json
nvd.nist.gov/vuln/detail/CVE-2026-59941
Left out here: the rest of 2 source descriptions. The JSON record has them.