CVE-2026-77187 Overview
CVE-2026-77187 is a stored Cross-Site Scripting (XSS) vulnerability in the My Calendar – Accessible Event Manager plugin for WordPress. The flaw affects all plugin versions up to and including 3.8.3. It resides in the before and after shortcode attributes, which fail to properly sanitize input and escape output. Authenticated attackers with contributor-level access or higher can inject arbitrary JavaScript into pages. The injected scripts execute in the browser of any user who visits an affected page. The weakness is tracked under CWE-79 (Improper Neutralization of Input During Web Page Generation).
Critical Impact
Authenticated contributors can inject persistent JavaScript that runs against administrators and site visitors, enabling session theft, forced administrative actions, and site defacement.
Affected Products
- My Calendar – Accessible Event Manager plugin for WordPress (all versions ≤ 3.8.3)
- WordPress sites permitting contributor-level or higher account registration
- Any WordPress deployment where the My Calendar plugin is active with shortcode rendering enabled
Discovery Timeline
- 2026-09-09 - CVE-2026-77187 published to the National Vulnerability Database (NVD)
- 2026-09-09 - Last updated in NVD database
Technical Details for CVE-2026-77187
Vulnerability Analysis
The My Calendar plugin exposes shortcodes that accept user-supplied before and after attributes. These attributes wrap the rendered event output with markup supplied by the shortcode author. The plugin renders these values without sufficient sanitization or output escaping. As a result, a contributor can embed a shortcode such as [my_calendar before="<script>...</script>"] inside a post. When another user, including an administrator, views the resulting page, the payload executes in their browser context.
Because the payload is stored server-side within post content, this qualifies as a stored (persistent) XSS. The scope is marked as changed, meaning script execution reaches beyond the vulnerable component into the broader WordPress admin session and visitor browsers.
Root Cause
The root cause is missing input sanitization and missing output escaping for shortcode attribute values. WordPress provides helpers such as wp_kses_post(), esc_attr(), and esc_html() for exactly this purpose. The vulnerable code paths in my-calendar.php, my-calendar-events.php, and my-calendar-shortcodes.php concatenate attribute values into HTML output without applying these helpers.
Attack Vector
Exploitation requires an authenticated account with contributor capability or higher. The attacker publishes or submits content containing a crafted My Calendar shortcode. Once the post is rendered — either awaiting review in the admin UI or published on the front end — the injected script executes against every viewer. No user interaction beyond page navigation is required.
// Patch excerpt from src/my-calendar-widgets.php
// Source: https://github.com/joedolson/my-calendar/commit/89bbf7314fac84cdb89e520e8b7b6d69eee8dd3c
} else {
$header = str_replace( 'mc-event-list ', 'mc-event-list no-events-fallback ', $header );
$class = ( str_contains( $args['template'], 'list_preset_' ) ) ? "list-preset $args[template]" : '';
- $return = $header . $navigation . '<li class="' . $class . '">' . wp_unslash( $args['substitute'] ) . '</li>' . $footer;
+ $return = $header . $navigation . '<li class="' . $class . '">' . wp_kses_post( wp_unslash( $args['substitute'] ) ) . '</li>' . $footer;
}
The fix wraps the attacker-influenced $args['substitute'] value in wp_kses_post(), which strips disallowed HTML tags and event-handler attributes before rendering.
Detection Methods for CVE-2026-77187
Indicators of Compromise
- Posts or pages containing My Calendar shortcodes with before= or after= attribute values that include <script>, on*= event handlers, or javascript: URIs.
- Unexpected outbound HTTP requests from administrator browsers to attacker-controlled domains immediately after loading a post that renders a My Calendar shortcode.
- New administrator accounts, altered user roles, or unexpected plugin installations that correlate with contributor account activity.
Detection Strategies
- Query the wp_posts table for post_content matching regex patterns that combine My Calendar shortcode names with <, on, or javascript: inside attribute values.
- Deploy a Web Application Firewall (WAF) rule that inspects shortcode attributes in POST requests to /wp-admin/post.php and /wp-admin/post-new.php.
- Enable Content Security Policy (CSP) reporting to surface inline script execution on pages that should only contain calendar output.
Monitoring Recommendations
- Audit contributor and author account activity for unusual post creation patterns or repeated edits containing shortcode payloads.
- Alert on modifications to privileged WordPress users, options, or plugin files following contributor logins.
- Review WordPress access logs for administrator sessions that render posts containing My Calendar shortcodes.
How to Mitigate CVE-2026-77187
Immediate Actions Required
- Update the My Calendar – Accessible Event Manager plugin to the version released after 3.8.3 that includes commit 89bbf7314fac84cdb89e520e8b7b6d69eee8dd3c.
- Audit all existing posts and pages for My Calendar shortcodes containing suspicious before or after attribute values and remove any injected script content.
- Rotate credentials and invalidate sessions for administrator accounts that may have viewed injected content.
Patch Information
The upstream fix is available in the plugin repository. See the GitHub commit and the Wordfence Vulnerability Report for details. Reference source paths for the vulnerable code include my-calendar-events.php, my-calendar-shortcodes.php, and my-calendar.php.
Workarounds
- Temporarily deactivate the My Calendar plugin until the patched release is deployed.
- Restrict contributor and author registration on the WordPress site to trusted users only.
- Enforce a strict Content Security Policy that disallows inline scripts (script-src 'self') to blunt payload execution.
- Deploy a WAF rule that blocks shortcode attribute values containing <script, onerror=, onload=, or javascript: strings.
# Update the plugin via WP-CLI to a version above 3.8.3
wp plugin update my-calendar
# Verify installed version
wp plugin get my-calendar --field=version
# List contributor and author accounts for review
wp user list --role=contributor --fields=ID,user_login,user_email,user_registered
wp user list --role=author --fields=ID,user_login,user_email,user_registered
# Search post content for suspicious shortcode attributes
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content REGEXP '\\[my_calendar[^]]*(before|after)=\"[^\"]*(<|javascript:|on[a-z]+=)';"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.