CVE-2026-68523: fulgur Unbounded Page Slicing Denial of Service
A tiny HTML snippet with an oversized CSS height value can force the fulgur HTML-to-PDF library to generate hundreds of thousands of page fragments, locking up the server's CPU and memory until it…
The problem
fulgur converts HTML and CSS into PDF documents, often in multi-tenant server environments where untrusted users supply the input.
Before version 0.19.0, the pagination engine sliced any body-direct child element whose CSS height exceeded the page height into one fragment per page, with no upper bound on the resulting page count. A height of 99999999px produces roughly 125,000 fragments. The pagination code then allocates a per-page vector and runs a full render loop over every fragment, exhausting CPU and memory.
A second variant uses a CSS value that resolves to positive infinity (for example via certain vh expressions or invalid computed values). The slicing loop decrements remaining -= last_slice_h on each iteration, but subtracting from infinity never reaches zero, so the loop never exits.
Proof of concept
A working proof-of-concept for CVE-2026-68523 in fulgur, with the exact payload below.
<html>
<body>
<!-- Variant 1: huge finite height -> ~125,000 page fragments, OOM/CPU exhaustion -->
<div style="height:99999999px"></div>
<!-- Variant 2: infinite height -> slicing loop never exits (infinite loop) -->
<div style="height:calc(infinity * 1px)"></div>
</body>
</html>The root cause is CWE-400 / CWE-835: the pagination loop in versions before 0.19.0 used the CSS-resolved height to compute page count with no guard, so attacker-controlled CSS drove an unbounded allocation and loop. For the finite case, page_count = ceil(element_height / page_height) is computed directly from untrusted input and then passed to vec![Vec::new(); page_count], making memory consumption proportional to the attacker-supplied value.
For the non-finite case, remaining -= last_slice_h where last_slice_h is +inf keeps remaining at +inf forever.
The fix in 0.19.0 (PR #501) introduces a MAX_PAGES constant that caps the slice loop, causing it to break early regardless of how large or non-finite the computed height is. Non-finite layout heights are also sanitized before the loop is entered, closing both attack paths.
The fix
Upgrade to fulgur 0.19.0 or later. If an immediate upgrade is not possible, validate or clamp CSS height values on body-level elements before passing HTML to fulgur, rejecting inputs where the resolved height would exceed a safe threshold (for example, 10x the target page height).
Related research
- high · 7.5CVE-2026-63128CVE-2026-63128: rmcp Streamable HTTP Unauthenticated Session-Table Memory Leak
- high · 7.5mistral.rs: Unbounded Remote Media Fetch and Video Frame Expansion DoS
- highCVE-2026-53530CVE-2026-53530: ratex-parser Process Abort via UTF-8 Multibyte Delimiter in \verb
- high · 8.2CVE-2026-63127CVE-2026-63127: rmcp OAuth Protected Resource Metadata Spoofing