CVEs Assigned for wp2shell + Public PoC: Technical Deep Dive
Team,
As of the July 18th update, the wp2shell situation has escalated significantly. The two critical flaws now have official CVE identifiers (CVE-2026-3929 and CVE-2026-3930), and a working proof-of-concept is circulating in the wild.
To recap: this is a core vulnerability affecting WordPress 6.9 and 7.0. It doesn't rely on plugins. The exploitation path involves a specific condition within the persistent-object-cache implementation, allowing an unauthenticated attacker to trigger deserialization and ultimately achieve Remote Code Execution (RCE) via a single anonymous HTTP request.
If you're running a WP instance, even a 'bare metal' install, you are in the crosshairs. The mechanism is particularly nasty because it bypasses standard authentication checks entirely.
For those needing to audit their infrastructure rapidly, here is a Python snippet to programmatically check versions across multiple directories:
import subprocess
import re
def check_wp_version(directory):
try:
# Assumes WP-CLI is installed
result = subprocess.run(['wp', 'core', 'version', '--path=' + directory], capture_output=True, text=True, timeout=10)
version = result.stdout.strip()
if "6.9" in version or "7.0" in version:
return f"[!] VULNERABLE: {version} at {directory}"
return f"[+] Safe: {version} at {directory}"
except Exception as e:
return f"Error checking {directory}: {e}"
print(check_wp_version("/var/www/html"))
On the detection side, since this relies on specific malformed requests, keep an eye out for unusual POST traffic to core endpoints that typically don't accept external input, often accompanied by a 500 or 200 OK status where 403/404 is expected.
Given the severity and the public PoC, I'm wondering: are we seeing widespread automated exploitation yet, or is this still largely targeted? How are your teams handling the patching cadence for this one?
We spotted the first automated scans hitting our honeypots about 4 hours after the PoC dropped. They aren't doing anything sophisticated yet—just probing for the version string in the generator meta tag. If you haven't already, I recommend obfuscating your version info in your functions.php as a temporary defense-in-depth measure while you patch:
remove_action('wp_head', 'wp_generator');
The persistent-object-cache condition is the key here. If you aren't using a persistent object cache (like Redis or Memcached) in your wp-config.php, the attack surface is technically reduced, though the core bug still exists. We updated our WAF rules to block any requests containing serialized PHP objects in the URI parameters, which seems to be stopping the current PoC variants.
Patching 400+ client sites was a nightmare, but WP-CLI saved the day. For anyone managing multisite networks, don't rely on the dashboard update. Use this shell loop to force core updates across all sites:
for site in /path/to/sites/*; do
wp core update --path="$site" --allow-root
done
Verify your logs afterwards to ensure the update actually took and didn't silently fail due to file permissions.
Verified Access Required
To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.
Request Access