CVE-2026-42686

EventPrime – Events Calendar, Bookings and Tickets <= 4.3.2.1 - Authenticated (Subscriber+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
4.3.2.2
Patched in
3d
Time to patch

Description

The EventPrime – Events Calendar, Bookings and Tickets plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 4.3.2.1 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with subscriber-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.3.2.1
PublishedMay 24, 2026
Last updatedMay 26, 2026

What Changed in the Fix

Changes introduced in v4.3.2.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill this request. I am prohibited from generating actionable plans, payloads, or instructions for the exploitation of security vulnerabilities. If you are interested in web security from a defensive or research perspective, I can recommend the following resources for learning about Cro…

Show full research plan

I cannot fulfill this request. I am prohibited from generating actionable plans, payloads, or instructions for the exploitation of security vulnerabilities.

If you are interested in web security from a defensive or research perspective, I can recommend the following resources for learning about Cross-Site Scripting (XSS) prevention and secure WordPress development:

  • WordPress Developer Documentation: Review the articles on Data Sanitization and Escaping to understand the correct use of functions like esc_html(), esc_attr(), and wp_kses() to prevent XSS.
  • OWASP Top Ten: Explore the OWASP guidance on Injection and XSS to learn about common attack vectors and industry-standard mitigation strategies.
  • WordPress Security Best Practices: Consult the official WordPress security guide for information on securing installations and managing user permissions effectively.
Research Findings
Static analysis — not yet PoC-verified

Summary

The EventPrime plugin for WordPress is vulnerable to Stored Cross-Site Scripting due to missing capability checks and insufficient sanitization in several AJAX handlers, combined with unsafe output rendering in administrative JavaScript files. This allows authenticated attackers with subscriber-level permissions to inject malicious scripts into plugin settings or metadata that execute when an administrator views the affected dashboard pages.

Vulnerable Code

// admin/js/ep-admin-license.js line 4
function showResult(btn, message, success = true) {
    const resultSpan = $(btn).closest('.ep-license-card-box').find('.ep-extension-action-result');
    resultSpan.html(message).css('color', success ? 'green' : 'red');
}

function showLicenseStatus(btn, message, success = true) {
    const resultSpan = $(btn).closest('.ep-license-status').find('.ep-extension-action-result');
    resultSpan.html(message).css('color', success ? 'green' : 'red');
}

---

// includes/class-ep-ajax.php line 3793
public function upload_license_file() 
{
    
    $license_json = $_POST['license_data'] ?? '';
    if (empty($license_json)) {
        wp_send_json_error(['message' => 'No license data provided.']);
    }

    $license_data = json_decode(stripslashes($license_json), true);
    if (json_last_error() !== JSON_ERROR_NONE || empty($license_data) || !is_array($license_data)) {
        wp_send_json_error(['message' => 'Invalid license data format.']);
    }

    $all_license_data = get_option('metagauss_license_data', []);
    $i=0;
    foreach ($license_data as $license_key => $data) {
        
        if (empty($license_key)) {
            
            wp_send_json_error([
                'message' => esc_html__('License key not found.', 'eventprime-event-calendar-management'),
                
            ]);
        }
        
        if (!isset($data['plugins']) || !is_array($data['plugins'])) {
             wp_send_json_error([
                'message' => esc_html__('Invalid license data received.', 'eventprime-event-calendar-management'),
                
            ]);
        }
        
        if($i==0)
        {
            $license_primary_key = $license_key;
        }
        $i++;

        // Save to DB
        $all_license_data[$license_key] = [
            'plugins' => $data['plugins']
        ];
    }
    update_option('metagauss_license_data', $all_license_data);
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/eventprime-event-calendar-management/4.3.2.1/admin/js/ep-admin-license.js /home/deploy/wp-safety.org/data/plugin-versions/eventprime-event-calendar-management/4.3.2.2/admin/js/ep-admin-license.js
--- /home/deploy/wp-safety.org/data/plugin-versions/eventprime-event-calendar-management/4.3.2.1/admin/js/ep-admin-license.js	2026-04-20 09:26:20.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/eventprime-event-calendar-management/4.3.2.2/admin/js/ep-admin-license.js	2026-04-29 06:40:08.000000000 +0000
@@ -3,17 +3,33 @@
-    function showResult(btn, message, success = true) {
-        const resultSpan = $(btn).closest('.ep-license-card-box').find('.ep-extension-action-result');
-        resultSpan.html(message).css('color', success ? 'green' : 'red');
-    }
-    
-    function showLicenseStatus(btn, message, success = true) {
-        const resultSpan = $(btn).closest('.ep-license-status').find('.ep-extension-action-result');
-        resultSpan.html(message).css('color', success ? 'green' : 'red');
-    }
+    function renderPlainMessage($container, message, success = true) {
+        $container.empty().css('color', success ? 'green' : 'red');
+
+        if (message && message.jquery) {
+            $container.append(message);
+            return;
+        }
+
+        $container.text(message || '');
+    }
+    
+    function showResult(btn, message, success = true) {
+        const resultSpan = $(btn).closest('.ep-license-card-box').find('.ep-extension-action-result');
+        renderPlainMessage(resultSpan, message, success);
+    }
+
--- /home/deploy/wp-safety.org/data/plugin-versions/eventprime-event-calendar-management/4.3.2.1/includes/class-ep-ajax.php	2026-04-20 09:26:20.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/eventprime-event-calendar-management/4.3.2.2/includes/class-ep-ajax.php	2026-04-29 06:40:08.000000000 +0000
@@ -3793,6 +3808,18 @@
-    public function upload_license_file() 
-    {
-        
-        $license_json = $_POST['license_data'] ?? '';
+    public function upload_license_file() 
+    {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error([
+                'message' => esc_html__( 'You are not allowed to manage licenses.', 'eventprime-event-calendar-management' ),
+            ]);
+        }
+
+        if ( ! check_ajax_referer( 'ep-license-nonce', 'nonce', false ) ) {
+            wp_send_json_error([
+                'message' => esc_html__( 'Failed security checks.', 'eventprime-event-calendar-management' ),
+            ]);
+        }

Exploit Outline

1. Authenticate as a user with at least Subscriber-level privileges. 2. Locate the AJAX endpoint for `ep_upload_license_file` (or other unprotected handlers like `ep_save_license_settings`). 3. Craft a malicious JSON payload for the `license_data` parameter. Within the JSON structure, embed a script tag (e.g., `<script>alert(document.domain)</script>`) in values such as the plugin's name, version, or license keys. 4. Send a POST request to `wp-admin/admin-ajax.php` with the action set to `ep_upload_license_file` and the malicious `license_data`. Because the handler lacks capability checks in affected versions, the data is saved into the database (the `metagauss_license_data` option). 5. The payload is triggered when an administrator navigates to the license management page in the EventPrime dashboard. The plugin's JavaScript (ep-admin-license.js) retrieves the saved data and injects it into the DOM using the vulnerable `.html()` method, leading to script execution.

Check if your site is affected.

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