Get your API key
CVE-2026-39919: the Ghostscript heap overflow that -dSAFER does not stop

CVE-2026-39919: the Ghostscript heap overflow that -dSAFER does not stop

CVE-2026-39919 is a heap buffer overflow in Ghostscript before 10.08.0, reached through a JPEG 2000 image in a PDF. -dSAFER does not mitigate it.

9 min read

CVE-2026-39919 is a heap-based buffer overflow in Ghostscript before 10.08.0, reachable by handing the renderer a PDF that embeds a JPEG 2000 image with mismatched component subsampling factors. The CVE record, assigned by VulnCheck and published on September 15, 2026, carries a CVSS 4.0 base score of 9.3 and a CVSS 3.1 base score of 9.8, both critical. The detail that matters operationally: -dSAFER does not help, because the corruption happens in the C decode path rather than through a PostScript operator. If a server of yours turns user-supplied PDFs into images, thumbnails, compressed copies or OCR text, Ghostscript is probably in that container, and it is probably the version your base image shipped.

What CVE-2026-39919 actually breaks

The bug lives in base/sjpx_openjpeg.c, the adapter between Ghostscript and the OpenJPEG JPEG 2000 decoder. When the components of a JPEG 2000 image declare different subsampling factors, the adapter selects its non-samescale output path. On that path, at sub-byte bit depths, it allocates a row buffer sized for packed output and then writes one full byte per output column regardless of bit depth. Every row overflows the allocation.

The overflow is not a clean off-by-one into padding. It runs past the row buffer into the metadata of Ghostscript's own chunk allocator, which is the property that upgrades the bug from a crash to a path toward code execution. The CVE record classifies it as CWE-122, heap-based buffer overflow. The fix is commit 0a8bf88e39db07b0751a58d6ec1cf992073e4dc1, shipped in the 10.08.0 release tagged on September 8, 2026, and tracked upstream as bug 709666. Credit for the finding goes to Alex Thomas of Wordfence and to Wordfence Argus.

The two published scores describe the same vector from two scoring versions:

MetricCVSS 4.0CVSS 3.1
Base score9.3 critical9.8 critical
VectorAV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Privileges requiredNoneNone
User interactionNoneNone

Coverage quoting "CVSS 9.8" is quoting the 3.1 figure from the same record, not a separate assessment. Neither score is an NVD-enriched score at the time of writing, they both come from VulnCheck as the assigning CNA.

Why -dSAFER does not save you

-dSAFER is the flag most teams treat as the Ghostscript hardening switch, and against the family of Ghostscript bugs that abuse PostScript operators it does real work. It does nothing here. The attacker never asks Ghostscript to open a file, run a pipe or invoke a device. They ask it to decode an image, and the adapter writes past the end of its own buffer while doing exactly that.

This distinction is worth internalizing because it changes what your defense-in-depth looks like. Operator-level restrictions gate what a document may ask the interpreter to do. Memory-safety bugs in the decoders sit below that gate. The controls that still apply are the ones that assume the process itself may be compromised: an unprivileged user, a read-only root filesystem, seccomp, no outbound network from the worker, short-lived containers, and a hard timeout. If your PDF worker can reach your database or your cloud metadata endpoint, a decoder bug in any of its dependencies is a full-service breach, not a crashed job.

The same reasoning applied to the LibreOffice OOXML heap overflow in headless converters earlier this year. Different parser, identical shape: attacker-controlled bytes reach a C parser in a process that has more privileges than the job needs.

Am I affected, and how do I check

You are affected if any process that touches untrusted documents links a Ghostscript build older than 10.08.0, or older than your distribution's patched package version. Start by finding out whether Ghostscript is present at all, because it is far more often a transitive dependency than a deliberate one.

Check the binary and the package:

# Upstream version string
gs --version
 
# Debian and Ubuntu bases
dpkg -l | grep -i ghostscript
 
# Alpine bases
apk info -v ghostscript
 
# RHEL, Fedora, Amazon Linux bases
rpm -q ghostscript

Then look for the transitive paths. ImageMagick shells out to Ghostscript for PDF, PS and EPS delegates, so an identify or convert call on a PDF is a Ghostscript call:

# Does ImageMagick have a Ghostscript-backed PDF delegate configured?
convert -list delegate | grep -iE 'ps|pdf|eps'
 
# Which binary would it reach for?
command -v gs gsx gswin64c

Audit your container images rather than your Dockerfiles, since base images and other packages pull Ghostscript in without a line of yours mentioning it:

# Inspect a built image without running the app
docker run --rm --entrypoint sh your-image:tag -c \
  'gs --version 2>/dev/null; dpkg -l 2>/dev/null | grep -i ghostscript'

Distribution packages carry backported fixes, so the upstream version number is the wrong thing to compare against. Ubuntu published USN-8791-1 on September 21, 2026, rating the issue important:

DistributionStatus as publishedReference
Ubuntu 26.04 LTSFixed in ghostscript 10.06.0~dfsg-3ubuntu1.1USN-8791-1
Ubuntu 24.04 LTSFixed in ghostscript 10.02.1~dfsg1-0ubuntu7.9USN-8791-1
Ubuntu 22.04 LTSFixed in ghostscript 9.55.0~dfsg1-0ubuntu5.14USN-8791-1
Debian bookwormPackage at 10.0.0, listed vulnerableDebian security tracker
Debian trixiePackage at 10.05.1, listed vulnerableDebian security tracker
Debian sidPackage at 10.08.0, fixedDebian security tracker
Upstream source buildsFixed in 10.08.0Artifex release gs10080

Debian statuses move, so re-read the Debian security tracker entry rather than trusting this snapshot. A machine reporting 9.55.0 on Ubuntu 22.04 can be fully patched, and a machine reporting 10.05.1 on Debian trixie may not be.

Where this bites in real PDF pipelines

Ghostscript sits under a surprising amount of document infrastructure, usually two or three dependency hops away from the code someone wrote. The exposure follows a single rule: does this process parse a PDF that a user supplied?

WorkloadParses inbound PDFs?Typical Ghostscript path
PDF thumbnail or preview generationYesImageMagick or gs rasterization
Server-side PDF compressionYesgs -sDEVICE=pdfwrite
OCR over uploaded scansOftenOCRmyPDF, which can use Ghostscript
PDF to image conversion for review flowsYesImageMagick delegate or direct gs
Print spooling of user documentsYesCUPS filter chain
HTML to PDF generationNoGhostscript usually absent from the chain

The OCR row deserves a caveat. OCRmyPDF made Ghostscript optional in version 17.0.0, with pypdfium2 available for rasterization, so newer installs may not link it at all. Check, do not assume in either direction.

Automatic preview generation is the nastiest case because nobody clicks anything. A user uploads a file, a worker picks it off a queue seconds later, and the decode runs with no human in the loop and no reason for anyone to look at the document first. If you cannot patch within the hour, pausing automatic preview and thumbnail jobs for PDFs is the mitigation with the best ratio of risk removed to functionality lost.

The architectural read: generation is not ingestion

A pipeline that generates PDFs from HTML and never re-parses an inbound PDF does not expose this class of bug. The bytes flow one way: a template plus data compile to HTML, a browser engine lays it out, and the PDF is written on the way out. Nothing in that chain decodes an attacker-supplied JPEG 2000 stream, because no attacker-supplied PDF ever enters it.

That is the shape of PDF4.dev's render path, and it is the honest limit of the claim. The moment a product accepts a PDF as input, the exposure is back, whatever the vendor. Merging uploaded files, compressing an existing document, extracting pages, repairing a damaged file: each of those needs a PDF parser, and a PDF parser is the thing this CVE attacks. The free browser-side tools on this site run pdf-lib and pdfjs in the visitor's own browser rather than on a server, which changes who owns the blast radius but does not make PDF parsing safe in general.

So the useful question for your own architecture is not "which vendor is safest", it is "how many of my services parse documents they did not create, and what can those services reach". Most teams find one or two workers doing PDF ingestion that were never meant to be security-relevant, running as root, on the same network as everything else.

What to do this week

Patch first, then reduce the surface. In order:

  1. Inventory every image and host with Ghostscript installed, including transitive installs, using the commands above.
  2. Upgrade to 10.08.0 upstream, or to your distribution's patched package. Rebuild and redeploy containers, since apt upgrade on a running container is lost on the next deploy.
  3. Pause automatic PDF preview and thumbnail generation until the patched images are live, if any of that runs on unreviewed uploads.
  4. Confirm that the workers doing document parsing run unprivileged, with no outbound network they do not need, and with a wall-clock timeout on every job.
  5. Wire an SBOM scan into CI so the next Ghostscript CVE is a failing build rather than a security bulletin someone happens to read.

The last point is the one that pays repeatedly. PDF libraries collected a long list of CVEs through 2026, and the pattern behind them is stable: parsers written in C, fed bytes from strangers, running in processes with more reach than the job requires. CVE-2026-39919 is the current instance, not the last one.

Sources: CVE record for CVE-2026-39919, Artifex Ghostscript CVE index, Ubuntu USN-8791-1, Debian security tracker, OSV entry, Ghostscript bug 709666, CISA Known Exploited Vulnerabilities catalog.

Free tools mentioned:

Compress PdfTry it freeRepair PdfTry it free

Start generating PDFs

Build PDF templates with a visual editor. Render them via API from any language in ~300ms.