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.
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 —...
3.1.6Exploitability
AV:NAC:LAT:PPR:NUI:NVulnerable System
VC:NVI:NVA:LSubsequent System
SC:NSI:NSA:N6.3/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