On September 17, WordPress shipped version 7.1.1 to fix CVE-2026-93485, a vulnerability researchers have dubbed Comment2Shell — and the name is uncomfortably accurate. The flaw allows a fully anonymous visitor to submit a comment containing a hidden script that is stored and rendered on the site. When a logged-in administrator later opens that page — something that happens routinely during comment moderation — the injected script executes in the admin's authenticated session and can pivot to arbitrary code execution on the underlying server.
This is the attack chain defenders dread most: an unauthenticated entry point, a privilege escalation path through a legitimate user's session, and a server-side execution outcome. WordPress powers a massive share of the public web, and comment functionality is enabled by default on a significant portion of those sites. If you operate WordPress properties — or your clients do — this is a patch-today event, not a patch-this-quarter event. The vendor advisory explicitly urges immediate updating.
Technical Analysis
Affected Products and Versions
- Product: WordPress core (self-hosted WordPress installations)
- Fixed version: 7.1.1 (released September 17, 2026)
- Affected versions: WordPress core releases prior to 7.1.1 with comment functionality reachable by anonymous visitors
- CVE: CVE-2026-93485
Sites that have fully disabled comments, or that gate comments behind authentication, have a materially smaller attack surface for this flaw — but the default WordPress configuration allows anonymous comment submission subject to moderation, which is precisely the scenario this vulnerability weaponizes.
How the Attack Works (Defender's View of the Kill Chain)
The Comment2Shell chain breaks down into three stages:
-
Stored injection (unauthenticated): An anonymous attacker submits a comment containing a malicious script payload. Insufficient sanitization in WordPress core's comment handling allows the payload to be stored and later rendered in an executable context rather than as inert text. This is a classic stored XSS primitive — but the delivery vehicle (a comment) is one of the most trusted, routinely-viewed content types on the platform.
-
Session hijack via admin view (no attacker interaction required): When a logged-in administrator loads the affected page — for example, during routine comment moderation in
wp-adminor while viewing the front-end post — the stored script fires with the administrator's full session privileges and nonces. From a detection standpoint, this stage looks like legitimate admin traffic: same cookies, same CSRF tokens, same IP. The browser is simply doing what the attacker's script tells it to do. -
Server-side code execution: Armed with the admin session, the script can invoke privileged WordPress functionality — installing a malicious plugin, editing theme PHP files via the built-in editor, or creating a rogue administrator account — any of which yields durable remote code execution as the web server user (
www-data,apache,nginx, or the php-fpm pool user).
The critical lesson for defenders: the XSS is the foot in the door, but the blast radius is defined by what an admin session is allowed to do. Sites that disable the file editor and plugin installation from the dashboard (via DISALLOW_FILE_EDIT and DISALLOW_FILE_MODS) dramatically shrink stage 3.
Exploitation Status
The flaw was disclosed and patched in WordPress 7.1.1 on September 17, 2026, with the project urging immediate updates. Given the trivial delivery mechanism (an HTTP POST to a public comment endpoint), defenders should assume weaponization timelines measured in days, not months. Comment endpoints are among the most-scanned paths on the internet, and stored-XSS-to-RCE chains against WordPress historically attract rapid mass exploitation for webshell deployment, SEO spam, and credential harvesting. Treat any pre-7.1.1 site with open comments as exposed, and audit for compromise rather than assuming a clean state.
Detection & Response
Detection here must cover all three stages: the malicious comment submission, suspicious admin-side activity following page views, and — most reliably — the server-side artifacts of code execution. The strongest signal is the web server or PHP process doing things WordPress never legitimately does: writing PHP files into upload directories, spawning shells, or making outbound connections.
---
title: Web Server Process Spawning Shell or System Utility
description: Detects PHP-FPM, Apache, or Nginx worker processes spawning shells or system utilities, consistent with post-exploitation after a WordPress stored XSS-to-RCE chain such as CVE-2026-93485 Comment2Shell.
references:
- https://thehackernews.com/2026/09/wordpress-comment2shell-flaw-can-turn.html
- https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/09/18
status: experimental
id: 9c1a2f47-3b6e-4d2a-8f51-7c0e9d4b2a18
tags:
- attack.execution
- attack.t1059.004
- attack.t1190
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/php-fpm'
- '/php-fpm8.3'
- '/php-fpm8.2'
- '/php-fpm8.1'
- '/apache2'
- '/httpd'
- '/nginx'
selection_child:
Image|endswith:
- '/bash'
- '/sh'
- '/dash'
- '/zsh'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/netcat'
- '/python'
- '/python3'
- '/perl'
- '/base64'
condition: selection_parent and selection_child
falsepositives:
- Rare legitimate WordPress plugins invoking system commands (e.g., image processing, backup tools) - tune by Image and CommandLine
level: high
---
title: PHP File Written to WordPress Uploads or Content Directory
description: Detects creation or modification of PHP files in wp-content/uploads or unexpected PHP writes under wp-content, a hallmark of webshell deployment after WordPress admin-session hijack via CVE-2026-93485.
references:
- https://thehackernews.com/2026/09/wordpress-comment2shell-flaw-can-turn.html
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/09/18
status: experimental
id: 4e7b91c2-6a3d-4f58-b902-1d5c8e7f3a64
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: file_event
product: linux
detection:
selection_path:
TargetFilename|contains:
- '/wp-content/uploads/'
- '/wp-content/themes/'
- '/wp-content/plugins/'
selection_ext:
TargetFilename|endswith:
- '.php'
- '.phtml'
- '.phar'
- '.php5'
- '.php7'
filter_uploads_legit:
TargetFilename|contains:
- '/wp-content/uploads/elementor/'
- '/wp-content/uploads/cache/'
condition: selection_path and selection_ext and not filter_uploads_legit
falsepositives:
- Legitimate theme or plugin updates performed through the dashboard - correlate with wp-admin update activity and maintenance windows
level: high
---
title: Suspicious Script Payload in WordPress Comment Submission
description: Detects HTTP POST requests to WordPress comment endpoints containing HTML script or event-handler payloads, consistent with the stored XSS delivery stage of CVE-2026-93485 Comment2Shell.
references:
- https://thehackernews.com/2026/09/wordpress-comment2shell-flaw-can-turn.html
- https://attack.mitre.org/techniques/T1189/
author: Security Arsenal
date: 2026/09/18
status: experimental
id: 2f6d8a15-9c4b-4e71-a3d8-5b2f6c9e1d07
tags:
- attack.initial_access
- attack.t1189
logsource:
category: webserver
detection:
selection_uri:
cs-uri|contains:
- 'wp-comments-post.php'
selection_method:
cs-method: 'POST'
selection_payload:
cs-body|contains:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
- 'fetch('
- 'XMLHttpRequest'
- 'wp-admin'
- 'admin-ajax.php'
condition: selection_uri and selection_method and selection_payload
falsepositives:
- Security scanning and QA testing - filter known scanner user agents and internal test ranges
level: medium
// Hunt: Suspicious POSTs to WordPress comment endpoints containing script payloads (delivery stage of CVE-2026-93485)
// Requires Apache/Nginx access logs ingested via Syslog/CEF or IIS/W3C logs if applicable
Syslog
| where TimeGenerated > ago(7d)
| where SyslogMessage has "wp-comments-post.php" and SyslogMessage has "POST"
| where SyslogMessage has_any ("<script", "onerror=", "onload=", "javascript:", "fetch(", "XMLHttpRequest")
| extend ClientIP = extract(@"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", 1, SyslogMessage)
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Attempts=count(), SamplePayload=any(SyslogMessage) by ClientIP, Computer
| order by Attempts desc
;
// Hunt: Web server / PHP-FPM spawning shells or download utilities (post-exploitation stage)
// Requires Linux auditd/Sysmon-for-Linux process events forwarded to Sentinel
Syslog
| where TimeGenerated > ago(7d)
| where SyslogMessage has_any ("php-fpm", "apache2", "httpd", "nginx")
| where SyslogMessage has_any ("/bin/bash", "/bin/sh", "/usr/bin/curl", "/usr/bin/wget", "nc -", "python3", "/usr/bin/perl")
| extend HostIP = HostIP
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Count=count(), Commands=make_set(SyslogMessage, 20) by Computer, HostIP
| order by Count desc
;
// Hunt: New admin user creation or plugin installation following comment activity (session-hijack stage)
// Requires WordPress/audit plugin logging or wp-admin access log analysis via CommonSecurityLog
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where RequestURL has_any ("admin-ajax.php", "user-new.php", "plugin-install.php", "theme-editor.php", "update.php")
| where RequestMethod == "POST"
| summarize FirstSeen=min(TimeGenerated), Requests=count(), DistinctURLs=dcount(RequestURL), URLs=make_set(RequestURL, 15) by SourceIP, DestinationHostName
| where DistinctURLs >= 2
| order by Requests desc
-- Velociraptor hunt: identify potential webshells dropped via WordPress admin-session hijack (CVE-2026-93485)
-- 1) PHP files created/modified in the last 14 days under wp-content (webshell staging)
SELECT FullPath, Size, Mtime, Ctime
FROM glob(globs=['/var/www/*/wp-content/uploads/**/*.php', '/var/www/*/wp-content/**/*.phtml', '/var/www/*/wp-content/**/*.phar'])
WHERE Mtime > (now() - 1209600)
ORDER BY Mtime DESC
;
-- 2) Processes spawned by the web server user that should not exist (reverse shells, downloaders)
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Username =~ 'www-data|apache|nginx'
AND (Name =~ '^(bash|sh|dash|nc|ncat|python|python3|perl|curl|wget)$'
OR CommandLine =~ '/dev/tcp/|bash -i|nc -e|base64 -d')
;
-- 3) Outbound connections held by web server processes (C2 or reverse shell channels)
SELECT Pid, Name, Status, LocalAddr, LocalPort, RemoteAddr, RemotePort
FROM netstat()
WHERE Name =~ 'php-fpm|apache2|httpd|nginx|bash|sh|nc|python'
AND Status =~ 'ESTABLISHED'
AND NOT RemoteAddr =~ '^(127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)'
#!/usr/bin/env bash
# Security Arsenal - CVE-2026-93485 (Comment2Shell) verification & hardening script
# Run on each WordPress host. Requires WP-CLI for full functionality.
set -euo pipefail
WP_PATH="${1:-/var/www/html}"
echo "=== Comment2Shell (CVE-2026-93485) Check: ${WP_PATH} ==="
# 1) Verify WordPress core version - MUST be 7.1.1 or later
cd "$WP_PATH"
CORE_VER=$(wp core version --allow-root 2>/dev/null || grep -oP "\$wp_version = '\K[^']+" wp-includes/version.php)
echo "[+] WordPress core version: ${CORE_VER}"
if [[ "${CORE_VER}" != "7.1.1" ]]; then
echo "[!] VULNERABLE - updating core to 7.1.1 now"
wp core update --version=7.1.1 --allow-root
wp core update-db --allow-root
else
echo "[OK] Core is patched."
fi
# 2) Sweep the comments table for stored XSS payloads
echo "[+] Scanning comments for script/event-handler payloads..."
wp db query "SELECT comment_ID, comment_post_ID, comment_author, comment_date FROM wp_comments WHERE comment_content LIKE '%<script%' OR comment_content LIKE '%onerror=%' OR comment_content LIKE '%onload=%' OR comment_content LIKE '%javascript:%' OR comment_content LIKE '%fetch(%';" --allow-root || true
echo "[!] If rows returned above, quarantine and delete those comments before admin review:"
echo " wp comment delete <comment_ID> --force --allow-root"
# 3) Audit admin accounts created in the last 30 days (rogue admin = session-hijack artifact)
echo "[+] Administrator accounts and recent creations:"
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --allow-root
# 4) Hunt for recently written PHP files under wp-content (webshell indicator)
echo "[+] PHP files modified in wp-content within last 14 days:"
find "${WP_PATH}/wp-content" -type f \( -name '*.php' -o -name '*.phtml' -o -name '*.phar' \) -mtime -14 -ls
# 5) Harden wp-config.php - kill the dashboard file editor and file mods (shrinks XSS-to-RCE blast radius)
CONFIG="${WP_PATH}/wp-config.php"
for directive in "DISALLOW_FILE_EDIT', true" "DISALLOW_FILE_MODS', true"; do
if ! grep -q "${directive}" "$CONFIG"; then
key="$(echo "$directive" | cut -d"," -f1 | tr -d " '")"
sed -i "/Happy publishing/i define( '${key}', true );" "$CONFIG"
echo "[+] Added define( '${directive} );' to wp-config.php"
fi
done
# 6) Block direct PHP execution in uploads via .htaccess (Apache)
UPLOADS_HT="${WP_PATH}/wp-content/uploads/.htaccess"
if [ ! -f "$UPLOADS_HT" ]; then
cat > "$UPLOADS_HT" <<'EOF'
<FilesMatch "\.(php|phtml|phar|php5|php7)$">
Require all denied
</FilesMatch>
EOF
echo "[+] Deployed PHP execution block in wp-content/uploads/.htaccess"
fi
echo "=== Done. Review findings above and rotate admin credentials if artifacts were found. ==="
Remediation
-
Patch immediately to WordPress 7.1.1. This is the vendor's explicit guidance. If you run managed fleets, force the update via WP-CLI (
wp core update --version=7.1.1) or your management plane rather than waiting for site owners. Verify the version programmatically across every property — don't trust dashboards. -
Treat pre-patch exposure as a compromise until proven otherwise. Any site running a vulnerable version with anonymous comments enabled should be audited: sweep the comments table for script payloads, enumerate administrator accounts for unauthorized additions, review installed plugins and themes against a known-good baseline, and hunt for PHP files under
wp-content/uploads. -
Neutralize the XSS-to-RCE pivot. Add
define( 'DISALLOW_FILE_EDIT', true );anddefine( 'DISALLOW_FILE_MODS', true );towp-config.php. Even if an admin session is hijacked by injected script, the attacker loses the two easiest paths to server-side execution (theme/plugin editor and plugin installation). Manage code changes through deployment pipelines instead. -
Block PHP execution in upload directories. Deny
.php,.phtml, and.pharexecution underwp-content/uploadsat the web server layer (.htaccess for Apache,locationblocks for Nginx). This kills the majority of webshell staging even after successful exploitation. -
Reduce the comment attack surface. Where business requirements allow, disable comments entirely, require authentication for comment submission, or hold all comments for moderation with sanitizing review tooling. Consider a WAF rule inspecting POST bodies to
wp-comments-post.phpfor script tags and event-handler attributes — this is a high-signal, low-noise filter. -
Protect the admin session. Enforce MFA on all administrator accounts, restrict
wp-adminaccess by IP allowlist or VPN where operationally feasible, and shorten session lifetimes. If any malicious comment artifacts are found, force password resets and revoke all admin sessions (wp user reset-password <id>plus session token invalidation), because the attacker may have harvested credentials or established persistence beyond the initial payload. -
Monitor for the post-exploitation behaviors, not just the CVE. Deploy the process-spawn and PHP-file-write detections above. The vulnerability will be patched; the TTP (web server spawning shells, uploads-directory webshells) recurs across every WordPress incident you will ever respond to.
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.