Leaving your mail slot open when the lock only works on certain door models
CVE-2026-39919 is a heap-based buffer overflow in Ghostscript's JPEG 2000 output adapter (base/sjpx_openjpeg.c). When Ghostscript renders a PDF containing a JPEG 2000 image whose components declare mismatched subsampling factors and sub-byte sample precision, the non-samescale output path allocates a 256-byte row buffer but writes up to 1,024 bytes per row — overflowing into adjacent heap metadata. Affected versions span Ghostscript 9.21 through 10.07.1 (when the OpenJPEG decoder is present). Artifex shipped the fix in 10.08.0 on September 8, 2026. The attack surface is any service that feeds untrusted PDFs into Ghostscript: WordPress thumbnail generation (via Imagick → ImageMagick → gs), document-management portals, invoice processors, mail gateways, and print spoolers.
The vendor stamped this CVSS 9.8 CRITICAL with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — network-accessible, trivial complexity, no auth, no interaction. That overstates the real risk by a full severity tier. Ghostscript is never directly network-exposed; the attacker must reach it through an intermediary application that accepts and processes PDFs. Wordfence's own researchers ran their exploit 10,240 times across ten stock Linux builds and *failed to achieve RCE* on any of them — they only popped a shell on a purpose-built server with tuned fonts, language settings, and system libraries. The public crash-test-case triggers the overflow but weaponization is build-specific. Code runs as the web-server or PHP-FPM user, not root. -dSAFER does not help. The bug is real and dangerous in the right environment, but calling it 9.8 is vendor-label inflation.
5 steps from start to impact.
Deliver crafted PDF to upload endpoint
- Target application accepts PDF uploads from untrusted users
- Application forwards PDFs to an image-processing or rendering pipeline
- Many modern web apps use client-side renderers (PDF.js) and never invoke server-side Ghostscript
- Upload forms may whitelist image-only formats (JPEG, PNG) and reject PDFs entirely
ImageMagick delegates to Ghostscript
gs to rasterize the PDF. The attacker does not need to invoke Ghostscript directly — the application does it for them. The processing is synchronous and occurs with the privileges of the web-server process.- ImageMagick's
policy.xmlhas not disabled the PDF/PS/EPS delegate - Ghostscript is installed and in
$PATH
- Since the 2019 ImageMagick CVE wave, many distributions ship
policy.xmlwith<policy domain="coder" rights="none" pattern="PDF" />by default — this blocks the entire chain - Containers built from minimal base images (distroless, Alpine without ghostscript) are not affected
policy.xml for PDF delegate rights: grep -r 'pattern="PDF"' /etc/ImageMagick*/policy.xmlHeap buffer overflow in sjpx_openjpeg.c
malloc chunk metadata on the heap.- Ghostscript version is 9.21–10.07.1
- OpenJPEG codec library is linked (default on all major distros)
- The overflow is deterministic, but the heap layout varies by allocator (glibc version, jemalloc, musl), ASLR, and compilation flags — making control of the overwrite target non-trivial across builds
gs --version < 10.08.0 is vulnerable. Note: distro backports may report an older version string but include the fix — check dpkg -l ghostscript or rpm -q ghostscriptHeap metadata corruption → controlled write
malloc chunk metadata to achieve an arbitrary write primitive. Wordfence researchers demonstrated two exploit variants that leverage this to redirect execution flow. However, the payload must be tuned per target: font configuration, locale settings, glibc version, and compiler flags all shift the heap layout. In 10,240 lab runs across 10 stock Linux builds, reliable RCE was only achieved on a purpose-built test server.- Attacker knows or can fingerprint the target's glibc version and Ghostscript build flags
- Heap layout is sufficiently predictable (no hardened allocator)
- Stock distro packages with default ASLR defeated exploitation in Wordfence's own lab testing
- Modern glibc heap hardening (safe-linking, tcache key) breaks naive metadata overwrites
- Alpine's musl allocator has a completely different chunk layout
Code execution as web-server user
www-data or nginx). This is an unprivileged account with read access to web application files (including database credentials in config files) but no direct root or domain access. Lateral movement requires a separate privilege-escalation or credential-harvesting step.- Steps 1–4 succeed on the target build
- Execution context is unprivileged — SELinux/AppArmor profiles on RHEL/Ubuntu may further confine the process
- Containerized deployments limit blast radius to the container namespace
- EDR agents will flag anomalous child processes from
gs
gs spawning /bin/sh, /bin/bash, or network connections; Falco rules for unexpected shell from image-processing containers<policy domain="coder" rights="none" pattern="PDF" /> and equivalent lines for PS, EPS, and XPS to /etc/ImageMagick-6/policy.xml (or ImageMagick-7 equivalent). This severs the most common exploitation chain (web app → ImageMagick → Ghostscript) completely. Deploy within 30 days per the noisgate mitigation SLA for HIGH findings. This is the single highest-leverage control.application/pdf MIME types and .pdf extensions from anonymous or low-privileged users. This eliminates the attacker's delivery mechanism. Apply at the WAF or application layer within 30 days. Note: this does not protect against PDFs arriving via email or API integrations.gs (or ghostscript) spawning shell interpreters (/bin/sh, /bin/bash, /usr/bin/python*) or making outbound network connections. This provides detection-in-depth even if the overflow succeeds. Most EDR platforms (CrowdStrike, SentinelOne, Defender for Endpoint) support custom behavioral rules.- Ghostscript
-dSAFERflag — Wordfence explicitly confirmed this does not protect against CVE-2026-39919. The overflow occurs in the image decoder path, which-dSAFERdoes not restrict. - File-extension or MIME-type validation alone — The malicious payload is a valid PDF with a valid JPEG 2000 stream. It passes all standard file-type checks.
- WAF signatures — No WAF vendor has published a signature for the malicious JP2 component structure embedded inside a PDF. The payload is binary and buried inside the PDF object stream.
- Upload size limits — The crash-test-case PDF is small (a few KB). Rate limiting and file-size caps do not prevent exploitation.
The supporting signals.
| In-the-wild exploitation | Not observed. Wordfence states they have "found no public evidence that it is being exploited today." Not listed on CISA KEV. No known campaigns. |
|---|---|
| Proof-of-concept | Crash PoC public; weaponized exploit NOT released. Wordfence developed two working exploits internally using their Argus tool but did not publish them. A minimal crash-test-case PDF is available. No repos named CVE-2026-39919 found on GitHub. Not indexed on pocindex.io as of October 2026. No Nuclei template, ExploitDB entry, or Metasploit module. |
| EPSS | 0.00784 (0.78%) — sits around the 65th percentile. Low probability of exploitation in the next 30 days, consistent with the build-specific exploitation difficulty. |
| KEV status | Not listed. No CISA KEV entry. No binding operational directive applies. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — 9.8. CVSS v4.0 score is 9.3. The AV:N rating is technically correct (network-delivered PDF) but misleading: the attacker cannot reach Ghostscript directly over the network; an intermediary application must process the file. |
| Affected versions | Ghostscript 9.21 through 10.07.1 when compiled with OpenJPEG support (default on all major distros). Vulnerable code was introduced in Ghostscript 9.21 (2017). |
| Fixed versions | Upstream: 10.08.0 (Sep 8, 2026). Ubuntu 26.04: 10.06.0~dfsg-3ubuntu1.1, 24.04: 10.02.1~dfsg1-0ubuntu7.9, 22.04: 9.55.0~dfsg1-0ubuntu5.14. Debian 12: 10.0.0~dfsg-11+deb12u8, Debian 13: 10.05.1~dfsg-1+deb13u2. AlmaLinux 10: fixed Oct 2 (RHSA-2026:74464). Ubuntu 20.04/18.04/16.04 still under evaluation. |
| Scanning / exposure | Ghostscript is not directly network-exposed, so Shodan/Censys/GreyNoise scans are not applicable. Vulnerability scanners (Nessus plugin 350296, Qualys, Rapid7) detect via OS package version. The real exposure metric is how many web apps process untrusted PDFs through ImageMagick → Ghostscript — this is common in WordPress, document portals, and invoice processors. |
| Disclosure timeline | Discovered: Aug 23, 2026 by Wordfence (Alex Thomas) during WordPress 7.1 security assessment. Upstream fix: Sep 8, 2026 (10.08.0). Public disclosure: Sep 15, 2026. |
| Reporter | Alex Thomas, Wordfence Threat Intelligence, using the Wordfence Argus AI-powered fuzzing system. |
Sources.
- Artifex Ghostscript CVE Index
- BleepingComputer — Ghostscript flaw lets hackers hijack servers via PDF uploads
- CybersecurityNews — Critical Ghostscript Flaw Lets Attackers Use Malicious PDFs to Execute Code
- SecurityOnline — Critical Ghostscript Vulnerability CVE-2026-39919
- Ubuntu Security CVE-2026-39919
- Red Hat Errata RHSA-2026:74464
- SecurityOnline — Ghostscript Flaw Allows Unauthenticated Remote Code Execution
Why this verdict
- Indirect attack surface, not direct network exposure. The CVSS vector marks AV:N, but Ghostscript is never a listening service. The attacker must first find an application that accepts untrusted PDFs and routes them through ImageMagick → Ghostscript. This adds a mandatory intermediary step that the 9.8 score ignores.
- Build-specific exploitation dramatically raises real-world AC. Wordfence ran their own exploit 10,240 times across 10 stock Linux distro builds and failed to achieve RCE on any of them. They only succeeded on a purpose-built test server with tuned fonts and libraries. This is effectively AC:H, not AC:L, which alone drops the vector to ~7.5.
- Unprivileged execution context limits blast radius. Code executes as
www-data/nginx/php-fpm, not root. Meaningful follow-on (DB credential theft, lateral movement) requires a separate privilege-escalation chain. SELinux and AppArmor profiles further confine the process on RHEL and Ubuntu. - ImageMagick policy.xml blocks the chain in many deployments. Since the 2019 Ghostscript CVE wave, many distro-default and hardened ImageMagick configurations ship with
rights="none"for the PDF delegate, severing the most common attack path before Ghostscript is ever invoked. - No in-the-wild exploitation, no KEV listing, EPSS < 1%. One month post-disclosure, there is zero evidence of active exploitation. The weaponized exploit has not been released. EPSS 0.78% confirms the market's assessment of low near-term exploitability.
- Role multiplier: Ghostscript is a document-rendering library, not a canonical high-value-role component (it is not a hypervisor, IdP, CA, PAM, backup agent, or network edge appliance). Its high-value deployment roles are (a) web application servers processing untrusted PDFs — blast radius is host-level (web-server user shell), not domain or fleet, requiring further privesc to escalate; (b) mail gateways scanning attachments — blast radius is host-level on the mail relay, significant but still requires chaining; (c) print servers — typically internal, low-sensitivity. None of these reach domain-takeover or fleet-compromise without additional exploitation chains. The floor is therefore HIGH (host compromise on servers processing sensitive documents in ≥1% of the installed base), not CRITICAL.
Why not higher?
A CRITICAL rating would require either direct network exploitability without intermediary dependencies, reliable universal exploitation, or a blast radius reaching domain/fleet/supply-chain scale. None apply here. The exploit is build-specific and failed on all stock distro builds in the researcher's own testing. The execution context is unprivileged. The most common attack path (ImageMagick PDF delegate) is blocked by default policy in hardened deployments.
Why not lower?
A MEDIUM rating would understate the risk. Ghostscript is installed on the vast majority of Linux servers as a transitive dependency, and many web applications do process untrusted PDFs through it without operators realizing. The crash PoC is public, the vulnerability is deterministic, and a motivated attacker with target-specific knowledge (obtainable via fingerprinting) can achieve RCE. The affected surface — document upload endpoints — is extremely common in enterprise environments. The combination of ubiquitous deployment, functional (if build-specific) RCE, and server-side untrusted-input processing keeps this firmly at HIGH.
Crowdsourced verification payload.
Run this script on each target host where Ghostscript may be installed. It checks both the upstream version and distro-backported package versions. Requires read access to the package manager (no root needed). Example: bash check_cve_2026_39919.sh
#!/usr/bin/env bash
# CVE-2026-39919 Checker — Ghostscript Heap Buffer Overflow (sjpx_openjpeg.c)
# Checks whether the installed Ghostscript is patched against CVE-2026-39919.
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
RESULT="UNKNOWN"
# --- Detect package manager and get installed version ---
get_pkg_version() {
if command -v dpkg-query &>/dev/null; then
dpkg-query -W -f='${Version}' ghostscript 2>/dev/null || echo ""
elif command -v rpm &>/dev/null; then
rpm -q --qf '%{VERSION}-%{RELEASE}' ghostscript 2>/dev/null || echo ""
elif command -v apk &>/dev/null; then
apk info -e ghostscript 2>/dev/null | head -1 || echo ""
else
echo ""
fi
}
# --- Check if Ghostscript is installed ---
if ! command -v gs &>/dev/null; then
echo "PATCHED — Ghostscript is not installed on this host."
exit 0
fi
GS_VERSION=$(gs --version 2>/dev/null || echo "unknown")
PKG_VERSION=$(get_pkg_version)
echo "Ghostscript binary version: $GS_VERSION"
echo "Package version: ${PKG_VERSION:-not determined}"
# --- Known-patched distro package versions ---
# Ubuntu 22.04
if echo "$PKG_VERSION" | grep -qE '9\.55\.0.*ubuntu5\.1[4-9]'; then
RESULT="PATCHED"
# Ubuntu 24.04
elif echo "$PKG_VERSION" | grep -qE '10\.02\.1.*ubuntu7\.(9|[1-9][0-9])'; then
RESULT="PATCHED"
# Ubuntu 26.04
elif echo "$PKG_VERSION" | grep -qE '10\.06\.0.*ubuntu1\.[1-9]'; then
RESULT="PATCHED"
# Debian 12
elif echo "$PKG_VERSION" | grep -qE '10\.0\.0.*deb12u([8-9]|[1-9][0-9])'; then
RESULT="PATCHED"
# Debian 13
elif echo "$PKG_VERSION" | grep -qE '10\.05\.1.*deb13u([2-9]|[1-9][0-9])'; then
RESULT="PATCHED"
# RHEL/Alma/Rocky — check if errata is applied
elif echo "$PKG_VERSION" | grep -qE 'el[89]_[0-9]+\.[1-9]' && rpm -q --changelog ghostscript 2>/dev/null | grep -qi 'CVE-2026-39919'; then
RESULT="PATCHED"
fi
# --- Upstream version check (covers source installs) ---
if [ "$RESULT" = "UNKNOWN" ]; then
MAJOR=$(echo "$GS_VERSION" | cut -d. -f1)
MINOR=$(echo "$GS_VERSION" | cut -d. -f2)
PATCH=$(echo "$GS_VERSION" | cut -d. -f3)
if [ "$MAJOR" -gt 10 ] 2>/dev/null; then
RESULT="PATCHED"
elif [ "$MAJOR" -eq 10 ] && [ "$MINOR" -gt 7 ] 2>/dev/null; then
RESULT="PATCHED"
elif [ "$MAJOR" -eq 10 ] && [ "$MINOR" -eq 8 ] && [ "${PATCH:-0}" -ge 0 ] 2>/dev/null; then
RESULT="PATCHED"
elif [ "$MAJOR" -eq 10 ] && [ "$MINOR" -le 7 ] 2>/dev/null; then
RESULT="VULNERABLE"
elif [ "$MAJOR" -eq 9 ] && [ "$MINOR" -ge 21 ] 2>/dev/null; then
RESULT="VULNERABLE"
fi
fi
# --- Also check ImageMagick policy (compensating control) ---
POLICY_BLOCKS_PDF="no"
for pfile in /etc/ImageMagick-*/policy.xml /usr/local/etc/ImageMagick-*/policy.xml; do
if [ -f "$pfile" ] && grep -q 'pattern="PDF"' "$pfile" && grep -q 'rights="none"' "$pfile"; then
POLICY_BLOCKS_PDF="yes"
break
fi
done 2>/dev/null
echo "ImageMagick PDF delegate blocked: $POLICY_BLOCKS_PDF"
# --- Output ---
if [ "$RESULT" = "PATCHED" ]; then
echo "PATCHED — Ghostscript version is fixed or includes the backported patch."
exit 0
elif [ "$RESULT" = "VULNERABLE" ]; then
if [ "$POLICY_BLOCKS_PDF" = "yes" ]; then
echo "VULNERABLE (mitigated) — Ghostscript is unpatched but ImageMagick PDF delegate is blocked."
else
echo "VULNERABLE — Ghostscript $GS_VERSION is affected by CVE-2026-39919. Patch immediately."
fi
exit 1
else
echo "UNKNOWN — Could not determine patch status. Verify manually."
exit 2
fi