Back to blog
CVE-2026-78006CVE-2026-78159WordPressThe Events CalendarRCECVE

The Events Calendar ≤ 6.17.4: 2 Unauthenticated RCEs via Comments

CVE-2026-78006 and CVE-2026-78159 (CVSS 9.8): unauthenticated code execution in the WordPress plugin The Events Calendar, through a comment awaiting moderation. Immediate mitigation.

September 14, 20267 min read

Two vulnerabilities rated CVSS 9.8 were published on September 12, 2026 against The Events Calendar, one of the most widely installed calendar plugins in the WordPress ecosystem. Both allow arbitrary code execution without authentication.

CVEAffected versionsVulnerable function
CVE-2026-78006all ≤ 6.17.4is_safe_widget_instance
CVE-2026-78159all ≤ 6.17.3Element_Classes::parse_array

Shared vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.

What makes these two remarkable isn't the outcome — an RCE in a WordPress plugin is sadly ordinary — but the path taken: the attack goes through the comment area, and the moderation queue does not protect you.

There is an immediate, free and effective mitigation: disable comments on events. More on that below.


The Exploitation Chain, Step by Step

This is the part worth understanding, because it invalidates a very common intuition.

The NVD description of CVE-2026-78006 is unusually detailed:

This is exploitable without authentication or approval because the plugin's V2 single-event template runs do_blocks() over buffered comment HTML, and WordPress returns a moderation-hash URL that allows an unauthenticated commenter to immediately view their own pending comment, delivering the injected block markup to the vulnerable code path before any moderation occurs.

Unpacking it:

1. The attacker posts a comment on an event page. The comment contains a forged Gutenberg block of type wp:legacy-widget.

2. The comment goes into moderation. This is where the usual defensive intuition kicks in: "it isn't published, so it can't do anything." That's wrong.

3. WordPress returns a moderation-hash URL. This is deliberate WordPress core functionality: so a visitor doesn't think their comment was lost, WordPress lets them view their own pending comment. That URL requires no authentication.

4. The attacker visits that URL. The event page renders, comment area included — with their pending comment inside it.

5. The plugin's V2 template runs do_blocks() over the buffered comment HTML. This is the core design defect: comment content — untrusted input supplied by an anonymous party — is treated as block markup to be interpreted.

6. The forged block reaches the vulnerable code and triggers execution.

Moderation never enters this sequence. The comment doesn't need approving: it only needs rendering once, and WordPress itself provides the means to cause that render.


The Two Flaws at the Sink

Both CVEs arrive at the same place by different routes. The plugin has a guard, is_safe_widget_instance(), meant to verify a widget instance is safe before processing. Both flaws bypass it, each in its own way.

CVE-2026-78006 — magic methods fire before the check

Due to insufficient protection in is_safe_widget_instance, which can be bypassed because PHP fires magic methods during its pre-parse, combined with enable_rendering_widget_copied() forging a valid wp_hash integrity attribute before unserialize() is reached.

Two mechanisms combine.

First, PHP's magic methods (__wakeup, __destruct, __toString…) fire during pre-parse — that is, before the safety check returns its verdict. The guard inspects an object whose mere construction has already produced effects.

Second, enable_rendering_widget_copied() forges a valid wp_hash integrity attribute. The integrity check meant to prevent deserialization of untrusted content is therefore satisfied by a value the attacker manufactured.

This is the same sequencing pattern already seen this month on PaperCut and MikroTik: the check exists, but something runs ahead of it.

CVE-2026-78159 — a plain array bypasses an object check

Due to insufficient validation of the widget 'classes' map, allowing a plain-array payload to bypass the is_safe_widget_instance() object check and reach the callable-invocation sink in Element_Classes::parse_array().

Here the bypass is more direct: the guard inspects objects. The attacker supplies a plain array. The check simply doesn't apply, and the payload reaches parse_array(), which invokes a callable — executing code.

This is the classic validation error: a check covering one data type while letting the others through.


Exploitation Conditions

Both CVEs share the same prerequisite, and that's where your immediate leverage sits:

This does require comments to be enabled and visible on events.

For CVE-2026-78159 the description is more precise still:

Exploitation requires that the targeted site has comments enabled on tribe_events posts and that at least one comment containing a crafted wp:legacy-widget block has been submitted.

In other words: a site whose events don't accept comments is not exploitable.

That's a real condition, not wishful thinking — and it's under your immediate control, with no update and no downtime.

Note: many sites have comments enabled on events without knowing it, because WordPress applies the global post setting by default to custom post types declaring comment support. Verify rather than assume.


Versions

CVEAffected versions
CVE-2026-78006all versions up to and including 6.17.4
CVE-2026-78159all versions up to and including 6.17.3

NVD exposes no fixed version number. Update to the latest available plugin release and check the vendor changelog — I won't assert a number NVD doesn't publish.

Check your version:

wp plugin get the-events-calendar --field=version
# Or without WP-CLI
grep -i "Version" wp-content/plugins/the-events-calendar/the-events-calendar.php | head -1

Detection

Comments containing block markup

The most direct signal — the payload is stored in the database:

SELECT comment_ID, comment_post_ID, comment_date, comment_approved,
       LEFT(comment_content, 200) AS excerpt
FROM wp_comments
WHERE comment_content LIKE '%wp:legacy-widget%'
   OR comment_content LIKE '%<!-- wp:%'
ORDER BY comment_date DESC;

A comment containing wp:legacy-widget has no legitimate reason to exist. No visitor writes that by accident.

Also check pending comments (comment_approved = '0'): the moderation queue is precisely where the payload lives, since the attack doesn't need approval.

File integrity

# PHP files modified recently under wp-content
find wp-content -name "*.php" -newermt "-30 days" -ls
# Compare against official checksums
wp core verify-checksums
wp plugin verify-checksums --all

Accounts and tasks

-- Recently created users, administrators especially
SELECT ID, user_login, user_email, user_registered FROM wp_users
ORDER BY user_registered DESC LIMIT 20;
wp cron event list

Server logs

Look for POST requests to wp-comments-post.php followed immediately by a GET to the same event page carrying a moderation-hash parameter, from the same address. That's the chain's exact signature.


Mitigation

1. Disable comments on events — immediately

The highest-value measure in this article: applicable in a minute, with no update, and it removes the exploitation condition for both CVEs.

Events → Settings → Display → uncheck comment display

Or globally for the post type:

// child theme functions.php
add_action( 'init', function () {
    remove_post_type_support( 'tribe_events', 'comments' );
}, 100 );

Close existing comments on events:

wp post list --post_type=tribe_events --format=ids | \
  xargs -d ' ' -I % wp post update % --comment_status=closed

2. Update the plugin

That's the only complete fix. Move to the latest available release.

3. Purge suspicious comments

After review, delete comments containing block markup — including pending ones, which are the most likely to carry the payload.

4. If you conclude there was a compromise

  1. Redeploy code from a trusted source rather than cleaning in place
  2. Audit the database: users, recently modified wp_options, scheduled tasks
  3. Rotate every secret: wp-config.php salts and keys, database credentials, admin passwords, extension API keys
  4. Force password resets and invalidate sessions
  5. Check files outside wp-content — an RCE can write anywhere the web process has rights

Why Continuous Monitoring of WordPress Plugins Matters

WordPress core is solid and updates itself. On virtually every compromised site, the risk comes from plugins — and the difficulty isn't updating them but knowing which are installed, at which version, on which site, when an organisation runs dozens managed by different teams.

With cveo.tech, inventory your WordPress sites and their plugins with exact versions, and get automatic alerts whenever a critical CVE affects one — so you act on publication day, not on defacement day.

Every Monday

The week's critical CVEs, in your inbox

One email a week: the CVSS ≥ 9 vulnerabilities published in the last seven days, plus our latest analyses. Nothing else.

Double opt-in by email. Unsubscribe in one click, any time.

Monitor CVEs with AI

AI-powered search, CVSS scoring, asset monitoring and automatic alerts.