← Back to Feed CACHED · 2026-09-21 16:16:44 · CACHE_KEY CVE-2026-87909
CVE-2026-87909 · CWE-74 · Disclosed 2026-09-19

The WP Photo Album Plus plugin for WordPress is vulnerable to Remote Code Execution in all versions via the…

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

Like leaving a loaded gun in a rarely-visited cabin that only people with a key and a specific toolkit can reach

CVE-2026-87909 is a remote code execution flaw in the wppa_image_magick function of the WP Photo Album Plus WordPress plugin (all versions through 9.2.09.002). When a user uploads a photo, the plugin builds an ImageMagick CLI command by concatenating the multipart upload filename into a string passed to exec(). The developer applied escapeshellcmd() to the *entire command*, which escapes shell metacharacters (;, |, ` `) but leaves spaces intact — meaning an attacker-controlled filename can inject *additional arguments* into the ImageMagick convert binary. ImageMagick's -write and MSL delegates have historically been abusable to write arbitrary files (webshells). The DB-layer filename sanitizer never touches the physical temp path, so the injection survives to the exec()` call. Authentication is required at the subscriber level or above.

The vendor's HIGH / 7.5 rating reflects the theoretical ceiling: authenticated RCE with full C/I/A impact. But the CVSS vector already includes AC:H (high complexity), and several compounding real-world prerequisites — WordPress open registration disabled by default, ImageMagick CLI required on the server *and* enabled in plugin settings, exec() not disabled by the host, and only ~10,000 active installs worldwide — mean the reachable population is a thin slice of a thin slice. The vendor score is technically defensible but overstates operational urgency for most defenders.

"Subscriber-auth RCE in a 10K-install photo plugin that needs ImageMagick CLI — real risk is narrow"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain subscriber-level WordPress account

The attacker needs at least a WordPress subscriber account on the target. WordPress ships with user registration disabled by default (Settings → General → Anyone can register is unchecked). On sites that do allow registration, Subscriber is the default role. The attacker either registers on an open-registration site or uses a compromised/insider credential.
Conditions required:
  • Target WordPress site has open registration enabled, OR attacker has existing subscriber credentials
Where this breaks in practice:
  • WordPress registration is off by default — fewer than ~15-20% of public WordPress sites enable it
  • Many sites that enable registration use CAPTCHA, email verification, or approval workflows that slow mass exploitation
Detection/coverage: Failed/bulk registration attempts visible in wp_users table and auth logs; Wordfence, Sucuri, and iThemes Security flag registration anomalies.
STEP 02

Confirm ImageMagick CLI is available and enabled in plugin settings

The vulnerable code path only fires when the plugin is configured to use the ImageMagick command-line binary (not the PHP Imagick extension). The plugin has a settings page where the admin must point it at the convert binary path. Additionally, the server must have exec() enabled in php.ini — many shared hosts add exec to disable_functions. If either condition is unmet, the attack path is dead.
Conditions required:
  • ImageMagick CLI tools installed on server
  • PHP exec() not in disable_functions
  • Plugin setting 'Use ImageMagick' enabled with valid binary path
Where this breaks in practice:
  • Most shared WordPress hosts disable exec() in production
  • GD is the more common image backend; admin must actively configure ImageMagick CLI in the plugin
  • Managed WordPress hosts (WP Engine, Kinsta, Flywheel) typically sandbox PHP execution and block shell calls
Detection/coverage: Server-side audit: check phpinfo() for disable_functions; check plugin option wppa_use_imagemagick in wp_options table.
STEP 03

Upload crafted filename via multipart form

The attacker uploads an image through the plugin's front-end upload form (if enabled for subscribers) with a specially crafted filename containing spaces and ImageMagick-specific argument flags. For example, a filename like innocent.jpg -write /var/www/html/wp-content/uploads/shell.php could inject a -write argument. The escapeshellcmd() wrapper will not strip the spaces, allowing the injected arguments to be parsed by the convert binary as separate parameters.
Conditions required:
  • Front-end upload capability enabled for subscriber role in plugin settings
  • Plugin processes the uploaded file through wppa_image_magick function
Where this breaks in practice:
  • The plugin's upload feature may be admin-only or restricted to higher roles depending on configuration
  • Filename length and character restrictions at the web server or WAF layer may truncate or reject the payload
  • The exact exploitation technique depends on the server's ImageMagick version and compiled delegates — modern ImageMagick (7.x) has restricted many dangerous delegates by default via policy.xml
Detection/coverage: WAF rules detecting unusual characters in multipart filename headers; ModSecurity CRS rules for ImageMagick abuse patterns; Wordfence firewall rules (added post-disclosure).
STEP 04

ImageMagick processes injected arguments

The convert binary parses the attacker-injected arguments. Depending on the ImageMagick version and policy.xml configuration, the attacker can use delegates like -write, ephemeral:, or MSL scripting to write an arbitrary PHP file (webshell) to a web-accessible directory. Modern ImageMagick 7.x with default policy.xml restrictions on MVG, MSL, EPHEMERAL, and URL delegates significantly limits this, but many older or misconfigured installations remain permissive.
Conditions required:
  • ImageMagick policy.xml does not block dangerous delegates
  • Web server document root is writable by the PHP process
Where this breaks in practice:
  • ImageMagick 7.x default policies block most dangerous delegates since the 2016 ImageTragick fixes
  • SELinux/AppArmor on hardened hosts may prevent writes outside temp directories
  • PHP open_basedir restrictions may constrain file writes
Detection/coverage: File integrity monitoring (OSSEC, Wazuh, Tripwire) on wp-content/uploads/; YARA rules for webshell signatures; endpoint detection for unexpected child processes spawned by convert.
STEP 05

Execute webshell for full server compromise

If the attacker successfully writes a PHP webshell, they access it via HTTP to gain arbitrary command execution as the web server user (typically www-data or apache). From here, standard post-exploitation follows: credential harvesting from wp-config.php, lateral movement, privilege escalation.
Conditions required:
  • Webshell successfully written to web-accessible path
  • No file integrity monitoring or real-time webshell detection
Where this breaks in practice:
  • EDR/AV agents detect common webshell patterns
  • Cloud WAFs (Cloudflare, Sucuri) can detect webshell access patterns
  • Immutable infrastructure (containers, read-only filesystems) prevents persistent file writes
Detection/coverage: Webshell scanners (PHP-malware-finder, YARA); access logs showing direct hits to newly created PHP files in upload directories; Wordfence malware scanner.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo evidence. Not listed in CISA KEV. No known campaigns or threat actor attribution as of 2026-09-22. Composite risk score of 43.8/100 per automated threat intel platforms.
Proof of ConceptNo public PoC identified. No exploit code on GitHub, ExploitDB, or Metasploit as of assessment date. The technique (ImageMagick argument injection via escapeshellcmd) is well-documented generically but no weaponized exploit specific to this CVE has surfaced.
EPSS Score0.00525 (0.53%) — 57th percentile. Indicates low predicted exploitation probability within 30 days. Consistent with the high friction chain.
CISA KEV StatusNot listed. No known due date for federal remediation.
CVSS VectorCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H — Network-reachable but high complexity, low-privilege auth required, no user interaction. Scope unchanged (no hypervisor/sandbox escape). Full impact triad when successful.
Affected VersionsAll versions of WP Photo Album Plus up to and including 9.2.09.002. Plugin author: opajaap.
Fixed Version9.3.02.003 (current release as of 2026-09-22, updated within hours of assessment). No explicit vendor advisory, but version jump from 9.2.x to 9.3.x and timing strongly suggest the fix is included. No distro backports applicable (WordPress plugin).
Install Base / Exposure~10,000 active WordPress installations per wordpress.org. This is a niche photo gallery plugin — roughly 0.002% of the ~500M WordPress sites globally. No Shodan/Censys/GreyNoise fingerprint exists for this plugin specifically.
Disclosure TimelineCVE reserved 2026-09-09, published 2026-09-19. Assigned by Wordfence (CNA). Wordfence firewall rules likely deployed to premium users on or before publication.
Researcher / OrgDiscovered and reported via the Wordfence Bug Bounty Program. Specific researcher name not disclosed in public advisory.
04 · The Call

Final Verdict
DOWNGRADED to MEDIUM (5.5/10)

Why this verdict

  • Authentication gate: Requires subscriber-level WordPress credentials. WordPress ships with registration disabled by default — the majority of the ~10,000 installs are not open-registration sites, compressing the unauthenticated attack surface to near zero.
  • ImageMagick CLI dependency: The vulnerable code path only executes when the admin has configured the plugin to use the ImageMagick CLI binary AND the server has exec() enabled in PHP. Many shared hosts disable exec(); many installs use GD instead. This eliminates a large fraction of the already-small install base.
  • High attack complexity confirmed: CVSS AC:H is warranted — exploitation requires chaining filename injection through escapeshellcmd() with a permissive ImageMagick policy.xml that doesn't block dangerous delegates. Post-ImageTragick (2016), most modern ImageMagick 7.x defaults restrict the delegates needed for file-write primitives.
  • Tiny blast radius: ~10,000 active installs worldwide. Even at 100% exploitation success, the absolute number of vulnerable targets is minuscule compared to any enterprise fleet's WordPress footprint.
  • Role multiplier: WP Photo Album Plus is a photo gallery widget — it is never a high-value infrastructure component. It does not run on domain controllers, hypervisors, CI/CD pipelines, or network edge appliances. The blast radius of a successful exploit is one WordPress web server (host-level). There is no identity-scale, fleet-scale, or supply-chain escalation path inherent to this component. No high-value-role floor applies.
  • No exploitation evidence: Zero PoCs, zero ITW campaigns, not KEV-listed, EPSS at 0.53%. The threat is entirely theoretical as of assessment date.

Why not higher?

The vendor's HIGH/7.5 would be appropriate if this were a widely-deployed component with low-friction exploitation. It is neither. The install base is ~10,000 (trivial), the chain requires authentication + a specific server configuration (ImageMagick CLI + exec() enabled + permissive policy.xml) that most real deployments lack, and there is zero exploitation evidence. No high-value deployment role raises the floor. Keeping this at HIGH would misallocate patching priority away from genuinely critical vulnerabilities in your fleet.

Why not lower?

When the full chain succeeds, the outcome is unauthenticated-equivalent RCE (webshell) on the WordPress host — a complete server compromise including database credentials, user data, and a pivot point into the hosting network. The technique (ImageMagick argument injection) is well-understood by attackers, and a motivated adversary targeting a specific site that runs this plugin with the right configuration could exploit it reliably. LOW would understate the impact for the small population that *is* vulnerable.

05 · Compensating Control

What to do — in priority order.

  1. Update to WP Photo Album Plus 9.3.02.003 immediately — The current release (9.3.02.003, published 2026-09-22) almost certainly contains the fix given the version jump and disclosure timing. This is the definitive remediation. As a MEDIUM verdict, the noisgate remediation SLA allows up to 365 days, but given this is a simple plugin update with no compatibility risk, deploy within the next maintenance window.
  2. Disable ImageMagick CLI in plugin settings — Navigate to WP Photo Album Plus → Settings → ImageMagick and disable the ImageMagick option or remove the binary path. The plugin falls back to PHP GD, which does not invoke exec() and eliminates the vulnerable code path entirely. This is the fastest compensating control — no mitigation SLA applies for MEDIUM, but do this today if you can't update immediately.
  3. Add exec() to PHP disable_functions — In php.ini, add exec to disable_functions if not already present. This kills the entire class of shell-execution vulnerabilities in PHP, not just this one. Requires a PHP-FPM/Apache restart. Verify the plugin and other functionality still work with GD fallback.
  4. Disable WordPress open registration — Ensure Settings → General → Anyone can register is unchecked on all WordPress instances. This eliminates the unauthenticated-to-subscriber escalation path. Audit with WP-CLI: wp option get users_can_register (should return 0).
  5. Deploy WAF rule for multipart filename injection — Add a ModSecurity or Cloudflare WAF rule that rejects multipart upload requests where the filename header contains ImageMagick argument flags (-write, -script, ephemeral:, msl:). This provides defense-in-depth even if the plugin isn't updated.
What doesn't work
  • WordPress core auto-updates — WordPress auto-updates core but does NOT auto-update plugins unless explicitly enabled per-plugin. Do not assume this plugin will self-patch.
  • PHP Imagick extension (PECL) — disabling or uninstalling the PHP Imagick extension does NOT help. This vulnerability uses the ImageMagick CLI binary via exec(), which is completely separate from the PHP extension.
  • File upload size limits — restricting upload file size does not prevent argument injection through filenames. The payload is in the filename metadata, not the file body.
06 · Verification

Crowdsourced verification payload.

Run this on each WordPress host where WP Photo Album Plus may be installed. Requires read access to the WordPress installation directory. Execute as the web server user or root: sudo bash check_cve_2026_87909.sh /var/www/html

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-87909 Checker — WP Photo Album Plus ImageMagick RCE
# Usage: bash check_cve_2026_87909.sh /path/to/wordpress
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

WP_PATH="${1:?Usage: $0 /path/to/wordpress}"
PLUGIN_DIR="$WP_PATH/wp-content/plugins/wp-photo-album-plus"

# Check if plugin is installed
if [ ! -d "$PLUGIN_DIR" ]; then
  echo "PATCHED — WP Photo Album Plus is not installed at $WP_PATH"
  exit 0
fi

# Extract version from readme.txt or the main plugin file
VERSION=""
if [ -f "$PLUGIN_DIR/wp-photo-album-plus.php" ]; then
  VERSION=$(grep -i 'Version:' "$PLUGIN_DIR/wp-photo-album-plus.php" | head -1 | sed 's/.*Version:[[:space:]]*//' | tr -d '[:space:]')
fi

if [ -z "$VERSION" ] && [ -f "$PLUGIN_DIR/readme.txt" ]; then
  VERSION=$(grep -i 'Stable tag:' "$PLUGIN_DIR/readme.txt" | head -1 | sed 's/.*Stable tag:[[:space:]]*//' | tr -d '[:space:]')
fi

if [ -z "$VERSION" ]; then
  echo "UNKNOWN — Could not determine WP Photo Album Plus version"
  exit 2
fi

echo "Detected WP Photo Album Plus version: $VERSION"

# Compare version — vulnerable: <= 9.2.09.002, fixed: >= 9.3.x
# Use sort -V for version comparison
FIXED_VERSION="9.2.09.003"
if printf '%s\n%s' "$FIXED_VERSION" "$VERSION" | sort -V | head -1 | grep -qx "$FIXED_VERSION"; then
  echo "PATCHED — Version $VERSION is at or above the fix threshold"
  exit 0
else
  # Additional check: look for escapeshellarg in the vulnerable function
  if grep -rq 'escapeshellarg' "$PLUGIN_DIR/wppa-photo-files.php" 2>/dev/null || \
     grep -rq 'escapeshellarg' "$PLUGIN_DIR/wppa-functions.php" 2>/dev/null; then
    echo "PATCHED — Version $VERSION contains escapeshellarg fix in image processing code"
    exit 0
  fi
  echo "VULNERABLE — Version $VERSION is affected by CVE-2026-87909"
  echo "  Affected: all versions <= 9.2.09.002"
  echo "  Fix: update to 9.3.02.003 or later"
  echo "  Mitigate: disable ImageMagick in plugin settings"
  exit 1
fi
07 · Sources

Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.