The NVD has published CVE-2026-78006, a CVSS 9.8 (Critical), network-exploitable vulnerability in The Events Calendar plugin for WordPress — one of the most widely deployed calendar/event plugins in the WordPress ecosystem, with hundreds of thousands of active installations. The flaw allows completely unauthenticated attackers to execute arbitrary code on the underlying web server.
The affected component is the is_safe_widget_instance function, present in all versions up to and including 6.17.4. If your organization runs WordPress with this plugin — and many marketing, municipal, higher-ed, and corporate sites do — treat this as an emergency patch event. Unauthenticated RCE against a public-facing CMS is the canonical initial access vector for webshell deployment, credential theft, and ransomware staging.
Technical Analysis
Affected Products and Versions
| Item | Detail |
|---|---|
| Product | The Events Calendar plugin for WordPress (StellarWP / The Events Calendar) |
| Affected versions | All versions ≤ 6.17.4 |
| Vulnerable function | is_safe_widget_instance |
| CVE / CVSS | CVE-2026-78006 / 9.8 (Critical), vector: NETWORK, no authentication required |
| Impact | Unauthenticated remote code execution on the web server |
| Reference | https://nvd.nist.gov/vuln/detail/CVE-2026-78006 |
Root Cause and Attack Chain
This is a PHP object injection / unsafe deserialization vulnerability, but the mechanics are subtler than a textbook unserialize() bug. From a defender's perspective, understanding the chain matters because it dictates what you hunt for:
- The plugin's V2 widget rendering pathway is reachable without authentication. No login, no nonce, no approval workflow — an anonymous internet user can reach the vulnerable code path.
enable_rendering_widget_copied()forges a validwp_hashintegrity attribute. The plugin attempts to protect a serialized widget payload with an HMAC-style integrity check. Due to the flaw, the attacker-controlled path computes a valid hash over an attacker-controlled payload, so the integrity gate passes legitimately.is_safe_widget_instanceperforms a pre-parse of the payload beforeunserialize()is reached. Critically, PHP fires magic methods (__wakeup,__destruct,__toString) during this pre-parse, which the safety check does not account for. The 'safety' validation itself becomes the code execution trigger.- Result: arbitrary PHP code execution in the context of the web server process (typically
www-data,apache, ornginx/ php-fpm worker user).
This is a classic example of why 'we validate it before unserializing' is not a safe pattern in PHP — any operation that instantiates or inspects the object graph can trigger magic methods. The integrity check passing also means the payload looks legitimate to naive WAF rules that assume a valid wp_hash implies a trusted request.
Post-Exploitation Expectations
Once code execution is achieved, expect the standard WordPress compromise playbook:
- Webshells dropped into
wp-content/uploads/, theme directories, or the plugin directory itself (randomly named.phpfiles, or legitimate-looking filenames likewp-cache.php,class-wp-upd.php). - Rogue administrator accounts created via direct database manipulation.
- Modified
wp-config.phpor injectedauto_prepend_filedirectives for persistence. - Outbound connections from the PHP-FPM/Apache worker process to attacker C2 for second-stage payloads.
Exploitation Status
The vulnerability pathway is network-reachable and unauthenticated with a CVSS of 9.8, and WordPress plugin vulnerabilities of this class are historically weaponized within days of disclosure — frequently by automated mass-exploitation bots that scan the IPv4 space for the plugin's fingerprint. At the time of publication, defenders should assume active or imminent in-the-wild exploitation and operate accordingly, regardless of whether CISA KEV inclusion has been formally published. Check KEV status daily until patched.
Detection & Response
The highest-fidelity detection surface is the web access log (requests carrying serialized PHP payloads against the widget rendering endpoints), followed by endpoint telemetry showing the web server process doing things a web server process should never do (spawning shells, writing PHP files to uploads, making outbound connections).
Sigma Rules
---
title: WordPress Web Server Process Spawning Shell or Command Interpreter
id: 3c7a2e91-4b5d-4f8e-9a1c-6d8e2f5b7c04
status: experimental
description: Detects PHP/Apache/Nginx worker processes spawning command interpreters, a strong post-exploitation indicator for CVE-2026-78006 unauthenticated RCE in The Events Calendar plugin.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-78006
- https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.execution
- attack.t1059.004
- attack.initial_access
- attack.t1190
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/php-fpm'
- '/php-fpm8.1'
- '/php-fpm8.2'
- '/php-fpm8.3'
- '/apache2'
- '/httpd'
- '/nginx'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/zsh'
- '/python'
- '/python3'
- '/perl'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/netcat'
condition: selection_parent and selection_child
falsepositives:
- Legitimate plugin update or backup scripts invoked by wp-cron (rare; verify script path)
level: high
---
title: PHP File Written to WordPress Uploads Directory
id: 8f1d4c26-7a9b-4e3d-b2f5-1c6a9d3e8b72
status: experimental
description: Detects creation of PHP files in wp-content/uploads, a classic webshell staging location following WordPress plugin RCE such as CVE-2026-78006.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-78006
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: file_event
product: linux
detection:
selection:
TargetFilename|contains: '/wp-content/uploads/'
TargetFilename|endswith:
- '.php'
- '.phtml'
- '.php5'
- '.php7'
- '.phar'
condition: selection
falsepositives:
- Rare; some media management plugins write PHP index files - whitelist known plugin paths
level: critical
---
title: HTTP Request Containing PHP Serialized Object Payload to WordPress
id: 5b2e8d41-9c3f-4a7e-8d6b-2e4f7a1c9d35
status: experimental
description: Detects web requests containing PHP serialized object signatures (O:length:) targeting WordPress widget endpoints, consistent with exploitation of unsafe deserialization flaws such as CVE-2026-78006 in The Events Calendar.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-78006
- https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_uri:
cs-uri|contains:
- '/wp-json/tribe/'
- 'widget'
- 'render'
selection_payload:
cs-body|contains:
- 'O:+8:"'
- 'O:8:"'
- 'O:%'
- '__wakeup'
- '__destruct'
condition: all of selection_*
falsepositives:
- Some legitimate plugin state sync operations use serialized data; baseline normal widget admin traffic and tune
level: high
KQL — Microsoft Sentinel (Web Logs via CEF/Syslog Ingestion)
This query hunts both the exploitation attempt (serialized object payloads in request bodies/URIs against the plugin's endpoints) and post-exploitation behavior (web worker spawning shells) assuming Linux syslog ingestion from the web tier.
// Hunt 1: Exploitation attempts - PHP serialized object payloads against The Events Calendar endpoints
union isfuzzy=true
(CommonSecurityLog
| where DeviceVendor =~ "Apache" or DeviceVendor =~ "Nginx" or DeviceProduct has "web"
| where RequestURL has_any ("/wp-json/tribe/", "widget", "render")
| where AdditionalExtensions has_any ("O:8:\"", "__wakeup", "__destruct") or RequestURL has_any ("O:8:%22", "O%3A8%3A%22")
| project TimeGenerated, SourceIP, RequestURL, RequestMethod, AdditionalExtensions, DeviceVendor),
(Syslog
| where SyslogMessage has_any ("/wp-json/tribe/", "tribe_events")
| where SyslogMessage has_any ("O:8:\"", "O%3A8%3A", "__wakeup", "__destruct")
| project TimeGenerated, HostIP, Computer, SyslogMessage)
| summarize AttemptCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, HostIP, Computer
| order by AttemptCount desc;
// Hunt 2: Post-exploitation - web server worker processes executing command interpreters
Syslog
| where Facility =~ "auth" or SyslogMessage has_any ("php-fpm", "www-data", "apache", "nginx")
| where SyslogMessage has_any ("/bin/sh", "/bin/bash", "curl ", "wget ", "nc -", "base64 -d")
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc;
Velociraptor VQL — Endpoint Hunt
Deploy this artifact across your web tier to identify recently created PHP files in upload/theme directories (webshell staging) and anomalous processes spawned by the web server user.
-- CVE-2026-78006 post-exploitation hunt:
-- 1) Recently written PHP files in wp-content uploads/themes (webshell staging)
-- 2) Processes spawned by the web server user (shells, downloaders)
SELECT FullPath, Size, Mtime, Atime, Mode
FROM glob(globs=[
'/var/www/**/wp-content/uploads/**/*.php',
'/var/www/**/wp-content/uploads/**/*.phtml',
'/var/www/**/wp-content/themes/**/*.php'
])
WHERE Mtime > (now() - 604800) -- files modified in last 7 days
AND FullPath !~ 'index\.php$'
ORDER BY Mtime DESC
-- Correlate with processes running as the web server user
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Username =~ 'www-data|apache|nginx|nobody'
AND (CommandLine =~ '(sh|bash|curl|wget|nc |python|perl|base64)'
OR Exe =~ '/(sh|bash|dash|python|perl|curl|wget|nc)$')
Remediation & Verification Script
Run this on each WordPress host to identify the installed plugin version, flag webshell artifacts, and pull the plugin update via WP-CLI where available.
#!/bin/bash
# CVE-2026-78006 - The Events Calendar plugin verification & remediation helper
# Run as root or with sudo on the WordPress host
WP_PATHS="/var/www /srv/www /home"
echo "=== [1] Locate The Events Calendar plugin and report version ==="
for base in $WP_PATHS; do
find "$base" -type d -name "the-events-calendar" -path "*wp-content/plugins*" 2>/dev/null | while read -r plugdir; do
ver=$(grep -m1 "Version:" "$plugdir/the-events-calendar.php" 2>/dev/null | grep -oE "[0-9]+\.[0-9]+\.[0-9]+")
echo "FOUND: $plugdir VERSION: $ver"
if [ -n "$ver" ]; then
major=$(echo "$ver" | cut -d. -f1); minor=$(echo "$ver" | cut -d. -f2); patchv=$(echo "$ver" | cut -d. -f3)
if [ "$major" -lt 6 ] || { [ "$major" -eq 6 ] && [ "$minor" -lt 17 ]; } || { [ "$major" -eq 6 ] && [ "$minor" -eq 17 ] && [ "$patchv" -le 4 ]; }; then
echo " [!] VULNERABLE to CVE-2026-78006 - update immediately"
else
echo " [OK] Version appears patched"
fi
fi
done
done
echo "=== [2] Attempt update via WP-CLI (preferred) ==="
for base in $WP_PATHS; do
find "$base" -maxdepth 4 -name "wp-config.php" 2>/dev/null | while read -r cfg; do
wpdir=$(dirname "$cfg")
echo "Updating via WP-CLI in $wpdir"
sudo -u www-data wp plugin update the-events-calendar --path="$wpdir" 2>/dev/null \
|| echo " WP-CLI update failed or not installed - update manually via wp-admin or vendor zip"
done
done
echo "=== [3] Hunt for PHP files in uploads (webshell staging) ==="
for base in $WP_PATHS; do
find "$base" -path "*wp-content/uploads*" -name "*.php*" -mtime -30 2>/dev/null
done
echo "=== [4] Grep access logs for serialized object payloads against widget endpoints ==="
for log in /var/log/apache2/access.log /var/log/nginx/access.log /var/log/httpd/access_log; do
[ -f "$log" ] && grep -Ei 'O(:|%3A)([0-9]+|%)8(%3A|:)%22|__wakeup|__destruct|/wp-json/tribe/' "$log" | tail -50
done
echo "=== [5] Check for rogue admin users created in last 30 days (via WP-CLI) ==="
for base in $WP_PATHS; do
find "$base" -maxdepth 4 -name "wp-config.php" 2>/dev/null | while read -r cfg; do
wpdir=$(dirname "$cfg")
sudo -u www-data wp user list --role=administrator --field=user_login --path="$wpdir" 2>/dev/null | while read -r adm; do
reg=$(sudo -u www-data wp user get "$adm" --field=user_registered --path="$wpdir" 2>/dev/null)
echo "ADMIN: $adm registered: $reg"
done
done
done
echo "=== Done. Review all flagged output before declaring the host clean. ==="
Remediation
- Update The Events Calendar plugin immediately to a version greater than 6.17.4 (the latest release from the vendor). All versions up to and including 6.17.4 are vulnerable. Update via wp-admin → Dashboard → Updates, WP-CLI (
wp plugin update the-events-calendar), or a fresh download from the WordPress plugin repository. - If you cannot patch immediately, deactivate the plugin. For an unauthenticated RCE of this severity, there is no acceptable WAF-only posture as a long-term workaround. If the business cannot tolerate deactivation, disable the V2 widget rendering pathway and place the site behind a WAF rule blocking request bodies containing PHP serialized object signatures (
O:<digits>:") to WordPress REST and widget endpoints — and treat that strictly as a bridge to patching within hours, not days. - Assume breach for internet-exposed sites that were running ≤ 6.17.4 between disclosure and patch. Perform the hunts above: audit
wp-content/uploadsand theme directories for unexpected PHP files, review administrator accounts and their registration dates, diffwp-config.phpandindex.phpagainst known-good copies, and check forauto_prepend_fileentries in.htaccess/php.ini/.user.ini. - Rotate credentials on any host confirmed or suspected compromised: WordPress salts/keys in
wp-config.php, database credentials, and any service accounts reachable from the web tier. - Verify CISA KEV status (https://www.cisa.gov/known-exploited-vulnerabilities-catalog) — federal civilian agencies and organizations following KEV-driven SLAs should apply the associated remediation deadline if the CVE is added.
- Hardening after the fact: ensure the web server user cannot write to plugin/theme directories outside of update windows, disable PHP execution in
wp-content/uploads(via nginxlocationblock or Apache.htaccess:php_flag engine off/ deny.phphandlers), and enforce file integrity monitoring on the WordPress root. - Reduce future exposure: enable automatic updates for WordPress plugins with a staged rollout, and inventory every site running this plugin — The Events Calendar is frequently installed and forgotten on secondary marketing and event sites that fall outside standard patch management scope.
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.