Event Organiser <= 3.12.8 - Missing Authorization
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:NTechnical Details
<=3.12.8# 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(oreo_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
- Entry Point: The plugin registers AJAX actions in
includes/event-organiser-ajax.phpusing:add_action( 'wp_ajax_eo_save_venue', 'eo_ajax_save_venue' ); - Handler: The function
eo_ajax_save_venue()is called. - Missing Check: Inside
eo_ajax_save_venue(), the code callscheck_ajax_referer( 'eo_venue_nonce', 'nonce' )to verify the CSRF token. - Vulnerability: After the nonce check, it proceeds to call functions like
eo_update_venue()oreo_insert_venue()without verifying if the current user has themanage_venuescapability. - Sink: Data is written to the
wp_postsandwp_termmetatables (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.
- Localization: The nonce is provided via
wp_localize_scriptinincludes/admin/class-eo-venue-admin.phporincludes/admin/venue-editor.phpusing the handleeo_venue_editor. - JS Object: The localized data is stored in the global JavaScript variable
event_organiser_venue_editor. - 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_editorobject. - 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].
- Subscribers can access the WordPress dashboard (
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
- Plugin: Install and activate "Event Organiser" version 3.12.8.
- User: Create a user with the
Subscriberrole. - 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 OKindicating 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_venuewith 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.
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
@@ -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.