This was found during a pentest, funded by the NLNnet foundation, conducted by Stefan Vink from Radically Open Security and the only High issue found.
WeasyPrint passes fetched image bytes directly to Pillow's generic format dispatcher without restricting the input format. When Ghostscript is installed on the host, Pillow's EpsImagePlugin invokes it to rasterize attacker-controlled EPS/PS input. Any content that can supply an image to WeasyPrint (an URL, CSS image value, SVG image reference, or data URI) can therefore drive untrusted PostScript into an external interpreter. On hosts running a Ghostscript version with a known -dSAFER bypass, this yields remote code execution.
The image pipeline reads an external response and hands the raw bytes to Pillow's format-agnostic Image.open, with no allowlist of safe raster formats:
with fetch(url_fetcher, url) as response: bytestring = response.read() mime_type = forced_mime_type or response.content_type
...
pillow_image = Image.open(BytesIO(bytestring))
Pillow selects the handler from the byte signature. For EPS/PS input it selects PIL.EpsImagePlugin, which invokes Ghostscript to rasterize the input when a Ghostscript executable is available. Modern Ghostscript builds may run with -dSAFER, but that does not remove the interpreter boundary — it only constrains it, and multiple CVEs have bypassed it.
The defect in WeasyPrint is that it dispatches untrusted bytes to a format handler capable of invoking an external interpreter, without first validating that the input is a format whose safe handling WeasyPrint can guarantee.
Hosts without Ghostscript installed do not reach the EPS rasterization path; that is an environment dependency, not an input-format guard within WeasyPrint.
postscript %!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 100 100 (/tmp/test-marker.txt) (w) file dup (test_GHOSTSCRIPT_MARKER\n) writestring closefile 0.5 setgray 0 0 100 100 rectfill showpage %%EOF
$ nc -lvnp 4444 127.0.0.1 & Ncat: Version 7.94 ( https://nmap.org/ncat ) Ncat: Listening on 127.0.0.1:4444
$ gs -dSAFER -dBATCH -dNOPAUSE -dPARANOIDSAFER -sDEVICE=ppmraw
-sOutputFile=/dev/null - < cve-2024-29510_payload.eps
...
Ncat: Connection from 127.0.0.1:51884.
bash: cannot set terminal process group (261755): Inappropriate ioctl for device
bash: no job control in this shell
tester@host:~$
This is a remote code execution vulnerability (via untrusted-input-to-external-interpreter dispatch).
Any deployment that renders untrusted or partially-untrusted HTML/CSS/SVG through WeasyPrint on a host where Ghostscript is installed along combination on general-purpose document-rendering servers.
{
"cwe_ids": [
"CWE-20"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-07T18:05:49Z",
"nvd_published_at": "2026-10-06T19:18:13Z",
"severity": "HIGH"
}