The NVD has published CVE-2026-75865, a CVSS 9.8 (Critical) vulnerability affecting the WPLP Cookie Consent – Cookie Banner & Consent Management for GDPR, CCPA & Google Consent Mode plugin for WordPress, in all versions up to and including 4.4.1. The flaw chains an authorization bypass on the plugin's WPLP connector REST endpoints with missing file type validation in the saas_upload_logo() function, allowing a fully unauthenticated, network-based attacker to upload arbitrary files — including PHP webshells — to the site's server. On a typical WordPress deployment where the uploads directory is web-accessible and PHP execution is enabled, that is a direct path to unauthenticated remote code execution.
If you run WordPress at any scale — and especially if you manage a fleet of client or marketing sites where consent-management plugins were installed to satisfy GDPR/CCPA requirements — treat this as an emergency patch item. Cookie consent plugins are deployed precisely because sites are public-facing, which means the vulnerable attack surface is internet-exposed by design.
Technical Analysis
Affected Component
- Product: WPLP Cookie Consent – Cookie Banner & Consent Management for GDPR, CCPA & Google Consent Mode (WordPress plugin)
- Affected versions: All versions ≤ 4.4.1
- CVE: CVE-2026-75865
- CVSS v3.1: 9.8 (Critical) — network-exploitable, no authentication, no user interaction
- Source: https://nvd.nist.gov/vuln/detail/CVE-2026-75865
How the Vulnerability Works (Defender's View)
The exploit chain has two weaknesses that compound each other:
-
Authorization bypass on WPLP connector REST endpoints. The plugin registers WordPress REST API routes (under a WPLP-specific namespace, typically
/wp-json/wplp-connector/...) that are reachable without a valid authenticated session or a valid nonce/capability check. Unauthenticated attackers can invoke functionality that was intended only for the plugin's backend service. -
Missing file type validation in
saas_upload_logo(). The logo-upload handler accepts an attacker-controlled file without validating the MIME type, extension, or content against an allowlist. WordPress's built-in upload hardening (wp_check_filetype_and_ext, upload mimes filtering) is bypassed or never invoked.
The result: an unauthenticated HTTP POST to the connector endpoint drops an arbitrary file — most usefully for the attacker, a .php file — into a web-accessible directory under wp-content/uploads/. The attacker then requests the uploaded file directly, and the web server executes it in the context of the PHP-FPM/Apache worker (typically www-data). From there, expect the standard post-exploitation sequence: webshell installation, credential harvesting from wp-config.php (database creds, auth keys/salts), lateral movement into the database, SEO spam/malvertising injection, or use of the host as a staging point for further compromise.
Exploitation Requirements and Status
- Authentication: None required
- Preconditions: A vulnerable plugin version reachable over HTTP/HTTPS; a writable upload path; PHP execution permitted in the uploads directory (default on most shared hosting and vanilla LAMP/LEMP stacks)
- Exploitation status: At time of writing, public reporting does not confirm widespread in-the-wild exploitation or CISA KEV inclusion — but CVSS 9.8 unauthenticated file-upload bugs in WordPress plugins are historically weaponized within days of disclosure, often by automated scanners and botnets. Do not wait for a KEV listing to act.
Why This Pattern Keeps Burning WordPress Sites
Arbitrary file upload via plugin REST endpoints with broken permission_callback handling remains one of the most reliably exploited WordPress vulnerability classes. The plugin ecosystem's shared-hosting deployment model means one vulnerable plugin equals full site compromise — and frequently server compromise, since multiple vhosts often share the same PHP user or the same database server.
Detection & Response
Hunting priorities, in order:
- Web access logs: Identify POST requests to WPLP connector REST endpoints, especially from IPs with no prior session/cookie history.
- Filesystem: Find executable files (
.php,.phtml,.phar,.htaccess) inwp-content/uploads/created recently. - Behavioral: Web server process (
php-fpm,apache2,nginxworker context) spawning shells or system binaries. - Outbound: Web server initiating unexpected egress (C2, payload staging).
SIGMA Rules
---
title: Unauthenticated Access to WPLP Cookie Consent Connector REST Endpoint
id: 3f8c2a91-7b4d-4e1a-b9c2-5d6e7f8a9b0c
status: experimental
description: Detects HTTP POST requests to the WPLP Cookie Consent plugin connector REST endpoints, associated with CVE-2026-75865 unauthenticated arbitrary file upload.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-75865
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection:
cs-method: 'POST'
cs-uri-stem|contains:
- '/wp-json/wplp'
- 'wplp-connector'
- 'saas_upload_logo'
condition: selection
falsepositives:
- Legitimate plugin backend synchronization traffic from the vendor SaaS service; baseline expected source IPs and user agents before tuning
level: high
---
title: Executable File Written to WordPress Uploads Directory
id: 8d4e1b52-3c6f-4a2d-9e7b-1f2a3c4d5e6f
status: experimental
description: Detects creation of PHP or script files inside wp-content/uploads, a hallmark of webshell deployment following exploitation of file upload vulnerabilities such as CVE-2026-75865.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-75865
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: file_event
product: linux
detection:
selection:
TargetFilename|contains: '/wp-content/uploads/'
TargetFilename|endswith:
- '.php'
- '.phtml'
- '.phar'
- '.php5'
- '.php7'
- '.htaccess'
condition: selection
falsepositives:
- Rare; legitimate plugins writing PHP into uploads is unusual. Some security plugins write .htaccess files intentionally - tune per environment
level: critical
---
title: Web Server Process Spawning Shell or System Tools
id: 2b7f9c14-5e8a-4d3b-a6c1-9f0e2d4c6b8a
status: experimental
description: Detects PHP-FPM, Apache, or Nginx worker processes spawning shells or reconnaissance tools, consistent with post-exploitation after webshell deployment via CVE-2026-75865.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-75865
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059.004
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/php-fpm'
- '/php8.1-fpm'
- '/php8.2-fpm'
- '/apache2'
- '/httpd'
- '/nginx'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/python'
- '/python3'
- '/perl'
- '/base64'
condition: selection_parent and selection_child
falsepositives:
- Some WordPress plugins legitimately shell out for image processing (ImageMagick) or backups - tune by CommandLine and child image
level: critical
KQL (Microsoft Sentinel / Defender)
This query assumes Apache/Nginx access logs are ingested into Sentinel via Syslog/CEF, or IIS logs via W3CIISLog if you run WordPress on Windows. It hunts for requests to the vulnerable connector endpoint and correlate-worthy upload behavior.
// Hunt 1: Requests to WPLP connector REST endpoints (CVE-2026-75865)
// Adjust table/columns to your log ingestion (Syslog, CommonSecurityLog, or W3CIISLog)
CommonSecurityLog
| where TimeGenerated > ago(14d)
| where RequestURL has_any ("wplp", "saas_upload_logo") or RequestURL has "/wp-json/"
| where RequestMethod == "POST"
| project TimeGenerated, SourceIP, RequestMethod, RequestURL, RequestProtocol, UserAgent=RequestClientApplication, DeviceHostName
| summarize Requests=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by SourceIP, RequestURL, UserAgent
| order by LastSeen desc;
// Hunt 2: Web server spawning suspicious child processes (webshell behavior)
// Requires endpoint telemetry from the WordPress host (MDE for Linux or Sysmon forwarded events)
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName has_any ("php-fpm", "apache2", "httpd", "nginx")
| where FileName has_any ("sh", "bash", "dash", "curl", "wget", "nc", "ncat", "python", "python3", "perl", "base64")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, AccountName, RemoteIP
| order by TimeGenerated desc;
// Hunt 3: Outbound connections from web server processes (C2 / payload staging)
DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName has_any ("php-fpm", "apache2", "httpd", "nginx", "php")
| where RemoteIPType == "Public"
| summarize Connections=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
| order by Connections desc;
Velociraptor VQL
Deploy this as a hunt across your WordPress hosts to find executable artifacts planted in uploads directories — the highest-fidelity indicator of successful exploitation.
-- Hunt for executable/webshell artifacts in WordPress uploads directories
-- CVE-2026-75865 post-exploitation triage
LET upload_roots = glob(glob="/*/wp-content/uploads", root="/var/www")
SELECT FullPath, Size, Mtime, Ctime, Mode,
hash(path=FullPath) AS Hash
FROM foreach(row=upload_roots,
query={
SELECT FullPath, Size, Mtime, Ctime, Mode
FROM glob(globs=["**/*.php", "**/*.phtml", "**/*.phar", "**/*.php5", "**/*.php7", "**/.htaccess"], root=FullPath)
})
WHERE Mtime > (now() - 60 * 86400 * 1000000) -- files modified in last 60 days
ORDER BY Mtime DESC
For process-level triage on a suspect host:
-- Enumerate network connections from web server / PHP processes
SELECT Pid, Name, Path, Status, Address Family=Family,
Laddr, Raddr, State
FROM netstat()
WHERE Name =~ '(php|apache|httpd|nginx)'
AND Raddr.IP.IsGlobalUnicast
Remediation & Verification Script
Run this on Linux WordPress hosts to inventory plugin versions, hunt for indicators of compromise, and harden the uploads directory against PHP execution (a defense-in-depth measure that breaks the webshell execution path even on unpatched sites).
#!/bin/bash
# CVE-2026-75865 - WPLP Cookie Consent arbitrary file upload
# Inventory, IoC sweep, and hardening script for WordPress on Linux
# Run as root or with sudo on each WordPress host
WP_ROOTS="/var/www /srv/www /home"
echo "=== [1] Locating WPLP Cookie Consent plugin installs ==="
find $WP_ROOTS -type d -name "*wplp*cookie*" -o -type d -name "*wpl-cookie-consent*" 2>/dev/null | while read -r plugindir; do
echo "FOUND: $plugindir"
grep -h -m1 "Version:" "$plugindir"/*.php 2>/dev/null | head -1
done
echo ""
echo "=== [2] Checking plugin version via WP-CLI (if available) ==="
if command -v wp >/dev/null 2>&1; then
find $WP_ROOTS -maxdepth 4 -name "wp-config.php" 2>/dev/null | while read -r cfg; do
sitedir=$(dirname "$cfg")
echo "--- $sitedir ---"
sudo -u www-data wp --path="$sitedir" plugin list --format=csv 2>/dev/null | grep -i "wplp\|cookie-consent"
done
else
echo "WP-CLI not installed; use manual plugin.php version check above"
fi
echo ""
echo "=== [3] Hunting for webshell artifacts in uploads (last 60 days) ==="
find $WP_ROOTS -path "*/wp-content/uploads/*" -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.phar" -o -name "*.php5" -o -name "*.php7" \) -mtime -60 -ls 2>/dev/null
echo ""
echo "=== [4] Reviewing access logs for connector endpoint hits ==="
for log in /var/log/apache2/access.log /var/log/nginx/access.log /var/log/httpd/access_log; do
[ -f "$log" ] && grep -iE "wplp|saas_upload_logo" "$log" | grep " POST " | tail -50
done
echo ""
echo "=== [5] Hardening: deny PHP execution in uploads directories ==="
find $WP_ROOTS -type d -path "*/wp-content/uploads" 2>/dev/null | while read -r updir; do
ht="$updir/.htaccess"
if [ ! -f "$ht" ] || ! grep -q "CVE-2026-75865-hardening" "$ht" 2>/dev/null; then
cat > "$ht" <<'EOF'
# CVE-2026-75865-hardening: block PHP execution in uploads
<FilesMatch "\.(php|phtml|phar|php[0-9])$">
Require all denied
</FilesMatch>
EOF
chown www-data:www-data "$ht" 2>/dev/null || chown apache:apache "$ht" 2>/dev/null
echo "Hardened: $ht"
fi
done
echo ""
echo "=== Done. If section [3] returned files, treat as compromised: isolate, image, and begin IR. ==="
Remediation
Priority 1 — Patch immediately.
-
Update the WPLP Cookie Consent plugin to a release newer than 4.4.1 as soon as the vendor ships a fixed build. Check Plugins → Installed Plugins in wp-admin, or via WP-CLI:
wp plugin update <plugin-slug>. Monitor the plugin's WordPress.org page and the vendor changelog for the fixed version number, and verify the update actually applied (auto-updates are frequently disabled on managed hosts). -
If no patch is available yet, deactivate and remove the plugin. A cookie banner is not worth a CVSS 9.8 unauthenticated file-upload primitive. Replace it temporarily with an alternative consent solution or a static banner.
-
Block PHP execution in
wp-content/uploads/at the web server layer (Apache.htaccess/php_flag engine off; Nginxlocation ~* /uploads/.*\.php$ { deny all; }). This is durable defense-in-depth against the entire vulnerability class, not just this CVE.
Priority 2 — Hunt before you assume you're clean.
Patching does not retroactively remove a webshell. Any site running a vulnerable version with the endpoint internet-reachable should be treated as potentially compromised:
- Sweep all uploads directories for executable files (script above).
- Review access logs for POST requests to WPLP connector endpoints going back at least 30–60 days, focusing on sources without WordPress session cookies and on requests immediately followed by GETs to new files under
/wp-content/uploads/. - Check for rogue admin users (
wp user list --role=administrator), modifiedwp-config.php, unexpected cron entries, and new files in the webroot outside WordPress's normal structure. - Rotate database credentials and WordPress auth keys/salts in
wp-config.phpif any IoC is found — assumewp-config.phpwas read.
Priority 3 — Reduce standing exposure.
- Enable auto-updates for plugins (with a staging/rollback plan) or enforce a 24–72 hour SLA for critical plugin CVEs.
- Put a WAF in front of WordPress with virtual patching rules for REST endpoint abuse; at minimum, alert on unauthenticated POSTs to
/wp-json/plugin namespaces. - Inventory every WordPress site you own or host. Plugin vulnerabilities in forgotten microsites and staging environments are how these bugs become breaches.
- Track the NVD entry for status changes and monitor CISA KEV for addition, which would impose federal remediation deadlines and signal confirmed exploitation: https://nvd.nist.gov/vuln/detail/CVE-2026-75865
Incident response trigger: If you find a dropped PHP file, evidence of code execution, or unknown outbound connections from the web server — isolate the host, preserve disk and memory images before remediation, and treat adjacent hosts and the site's database as in-scope for the investigation.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.