Skip to main content
Vulnerability Database/CVE-2026-106443

CVE-2026-106443: WeasyPrint RCE Vulnerability

CVE-2026-106443 is a remote code execution flaw in WeasyPrint that allows attackers to execute arbitrary code through malicious image formats. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-106443 Overview

CVE-2026-106443 affects WeasyPrint, a Python library that converts HTML and CSS documents into PDF files. Versions prior to 70.0 pass fetched image bytes to Pillow's generic image dispatcher without excluding Encapsulated PostScript (EPS) or PostScript formats. When Ghostscript is installed on the host, Pillow's EpsImagePlugin invokes the interpreter against attacker-controlled PostScript content. The resulting interpreter execution can lead to remote code execution if the installed Ghostscript version contains a usable sandbox bypass. The flaw is tracked under [CWE-20: Improper Input Validation].

Critical Impact

An attacker who can supply an HTML img URL, a CSS image value, an SVG image reference, or a data URI to a WeasyPrint rendering pipeline can trigger PostScript interpretation and potentially achieve remote code execution on hosts with Ghostscript installed.

Affected Products

  • WeasyPrint versions prior to 70.0
  • Deployments running WeasyPrint alongside Ghostscript on the host
  • Applications exposing HTML-to-PDF rendering endpoints that accept user-supplied content

Discovery Timeline

  • 2026-10-06 - CVE-2026-106443 published to NVD
  • 2026-10-06 - Last updated in NVD database
  • Fix released - WeasyPrint 70.0 published on GitHub with the patched image pipeline

Technical Details for CVE-2026-106443

Vulnerability Analysis

The vulnerability lives in weasyprint/images.py, which handles image loading for the renderer. WeasyPrint fetches bytes referenced from HTML img tags, CSS image values, SVG image references, and data: URIs. Those bytes are then handed to Pillow's generic Image.open dispatcher. Pillow autodetects the image format and selects a plugin. For EPS and PostScript inputs, Pillow dispatches to EpsImagePlugin, which shells out to a locally installed Ghostscript binary to rasterize the content. The attacker therefore controls the PostScript program that Ghostscript interprets. Depending on interpreter permissions and the specific Ghostscript version in use, this yields file access, side effects, or full command execution when a sandbox bypass is available.

Root Cause

The root cause is missing format allow-listing in the image loader. WeasyPrint did not filter EPS or PostScript before invoking Pillow, which exposes a format that forwards content to an external interpreter. This is a classic improper input validation issue [CWE-20] where trust boundaries between remote content, Pillow, and Ghostscript were not enforced.

Attack Vector

An authenticated or low-privileged user who can submit HTML or CSS to a WeasyPrint-backed service supplies a reference to an EPS payload. The payload can be remote (<img src="https://attacker.tld/x.eps">), inline (url(data:application/postscript;base64,...)), or embedded in SVG. During PDF rendering, Pillow routes the bytes to EpsImagePlugin and Ghostscript executes the attacker's PostScript on the server.

python
 from xml.etree import ElementTree
 
 import pydyf
-from PIL import Image, ImageFile, ImageOps
+from PIL import EpsImagePlugin, Image, ImageFile, ImageOps
 from tinycss2.color5 import parse_color
 
 from . import DEFAULT_OPTIONS
# Source: https://github.com/Kozea/WeasyPrint/commit/39cd37ce1610bd890388e26591c569db1cbab542
# This patch imports EpsImagePlugin explicitly so WeasyPrint can disable EPS rendering
# in the image-loading path, preventing Pillow from dispatching attacker-controlled
# PostScript to Ghostscript.

Stop Remote Code Execution Before It Runs

Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.

Stop Exploit Attempts

Detection Methods for CVE-2026-106443

Indicators of Compromise

  • WeasyPrint rendering processes spawning gs or ghostscript child processes during HTML-to-PDF jobs.
  • Inbound HTML, CSS, or SVG content referencing .eps files or data:application/postscript URIs.
  • Outbound network connections from the rendering host to untrusted domains fetching image assets with EPS content types.
  • Unexpected file writes, shell invocations, or network sockets originating from the Python process hosting WeasyPrint.

Detection Strategies

  • Inspect HTTP request bodies submitted to PDF-generation endpoints for EPS/PostScript references and data: URIs with PostScript MIME types.
  • Correlate WeasyPrint worker PIDs with child process creation of Ghostscript binaries in endpoint telemetry.
  • Alert on Python interpreter processes that execute gs, /usr/bin/gs, or any Ghostscript variant followed by anomalous file or network activity.

Monitoring Recommendations

  • Enable process ancestry logging so Ghostscript invocations under WeasyPrint workers are visible in the SIEM.
  • Capture outbound DNS and HTTP from PDF-rendering hosts and alert on new, uncategorized destinations.
  • Track WeasyPrint version strings across container images and inventory any instance below 70.0.

How to Mitigate CVE-2026-106443

Immediate Actions Required

  • Upgrade WeasyPrint to version 70.0 or later on every host and container image.
  • Remove Ghostscript from systems running WeasyPrint if PostScript rasterization is not a product requirement.
  • Audit application code to confirm user-supplied HTML, CSS, SVG, and data URIs are passed only to patched WeasyPrint builds.

Patch Information

The fix is released in WeasyPrint 70.0. The relevant change in weasyprint/images.py imports EpsImagePlugin and disables EPS rendering in the loader. See the GitHub Security Advisory GHSA-r543-q48m-4c9j, the WeasyPrint v70.0 release notes, and the patch commit 39cd37c.

Workarounds

  • Uninstall Ghostscript on hosts where WeasyPrint runs; the vulnerable rasterization path is not reached without it.
  • Filter user-supplied HTML, CSS, and SVG to reject EPS and PostScript references and data: URIs with PostScript MIME types before invoking WeasyPrint.
  • Run WeasyPrint inside a least-privilege sandbox or container with no outbound network access and a read-only filesystem to limit interpreter-reachable side effects.
bash
# Configuration example: upgrade WeasyPrint and remove Ghostscript on Debian/Ubuntu
pip install --upgrade 'weasyprint>=70.0'
apt-get remove --purge ghostscript

# Verify the installed version
python -c "import weasyprint; print(weasyprint.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.