CVE-2025-68007

Event Espresso 4 Decaf <= 5.0.37.decaf - Missing Authorization to Unauthenticated Settings Change

mediumMissing Authorization
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
5.0.53.decaf
Patched in
27d
Time to patch

Description

The Event Espresso – Event Registration & Ticketing Sales plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 5.0.37.decaf. 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:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=5.0.37.decaf
PublishedJanuary 15, 2026
Last updatedFebruary 10, 2026
Affected pluginevent-espresso-decaf
Research Plan
Unverified

This research plan outlines the steps to exploit **CVE-2025-68007**, a missing authorization vulnerability in **Event Espresso 4 Decaf** that allows unauthenticated settings changes. ### 1. Vulnerability Summary The vulnerability exists because a configuration update handler (likely within an AJAX …

Show full research plan

This research plan outlines the steps to exploit CVE-2025-68007, a missing authorization vulnerability in Event Espresso 4 Decaf that allows unauthenticated settings changes.

1. Vulnerability Summary

The vulnerability exists because a configuration update handler (likely within an AJAX or admin_init hook) fails to perform a current_user_can('manage_options') check. In the "Decaf" (free) version of Event Espresso, certain setup or configuration functions were exposed to unauthenticated users, potentially via the wp_ajax_nopriv_ action or by processing global $_POST variables during admin_init without sufficient authorization. This allows an attacker to modify the plugin's core configuration, including organization details, registration settings, or even gate certain site behaviors.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php (common for EE AJAX) or / (if via init/admin_init).
  • Action: ee_update_config or ee_set_config (inferred EE action names).
  • Parameter: ee_config (array containing settings).
  • Authentication: None required (Unauthenticated).
  • Preconditions: The plugin must be active. A nonce may be required if the check_ajax_referer function is called, but often in "Missing Authorization" cases, the nonce is either missing or exposed publicly.

3. Code Flow (Inferred)

  1. Request Entry: An unauthenticated user sends a POST request to admin-ajax.php.
  2. Hook Trigger: WordPress triggers admin_init or a wp_ajax_nopriv_ee_... action.
  3. Handler Execution: The plugin's handler (e.g., EE_Admin_Page::save_settings or EE_Config::update_configuration) is invoked.
  4. Authorization Failure: The code checks for a nonce (perhaps) but skips a current_user_can() check, assuming only admins can reach that logic.
  5. Sink: The update_option('ee_config', ...) function is called with user-supplied data from $_POST['ee_config'].

4. Nonce Acquisition Strategy

Event Espresso typically localizes its nonces via wp_localize_script. Since the vulnerability is unauthenticated, we need to find a public page where these scripts are loaded.

  1. Create a Public Page: Event Espresso scripts are usually enqueued on pages containing event shortcodes.
    • Command: wp post create --post_type=page --post_title="Events" --post_status=publish --post_content='[ESPRESSO_EVENTS]'
  2. Identify JS Variable: Look for the localized object, usually named ee_admin_js_strings or EE_JS.
  3. Extraction:
    • Navigate to the newly created page.
    • Use browser_eval to extract the nonce:
      browser_eval("window.ee_admin_js_strings?.nonce || window.EE_JS?.ajax_nonce")
  4. Action String: If check_ajax_referer is used, the action is likely 'ee_admin_nonce' or 'espresso_ajax_nonce'.

5. Exploitation Strategy

We will attempt to change the Organization Name and Organization Email in the Event Espresso configuration.

  • Step 1: Discover Entry Point
    Test if the plugin responds to the ee_update_config action.
  • Step 2: Craft Payload
    The payload will target the ee_config option, specifically the org_data key.
  • Step 3: Send HTTP Request
    • URL: http://localhost:8888/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      action=ee_update_config&ee_config[org_data][name]=HACKED_ORG&ee_config[org_data][email]=attacker@example.com&ee_nonce=[EXTRACTED_NONCE]
      
    • Note: If ee_update_config is not the correct action, try ee_admin_ajax with ee_ajax_action=update_config.

6. Test Data Setup

  1. Install and activate Event Espresso Decaf <= 5.0.37.decaf.
  2. Ensure the plugin is initialized (visit the settings once in the admin UI to generate default ee_config).
  3. Create the public nonce-leak page:
    wp post create --post_type=page --post_content='[ESPRESSO_EVENTS]' --post_status=publish

7. Expected Results

  • The server should return a 200 OK or a JSON success response (e.g., {"success":true}).
  • The ee_config option in the database will be updated.

8. Verification Steps

After sending the POST request, verify the change via WP-CLI:

# Check if the organization name was updated
wp option get ee_config --format=json | jq '.[ "org_data" ][ "name" ]'
# Expected output: "HACKED_ORG"

# Check if the organization email was updated
wp option get ee_config --format=json | jq '.[ "org_data" ][ "email" ]'
# Expected output: "attacker@example.com"

9. Alternative Approaches

If the admin-ajax.php route fails, the vulnerability might lie in a direct admin_init hook that processes $_POST data regardless of the URL:

  1. Direct POST to Home: POST /?ee_action=update_config&ee_config[...]
  2. Critical Pages Setup: Some versions of EE have a "Setup Wizard". Try targeting action=ee_setup_wizard_save_settings.
  3. Check for specific settings: Try changing ee_config[registration][enforce_login] to 0 to see if it allows unauthenticated registrations that were previously restricted.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Event Espresso Decaf plugin for WordPress is vulnerable to unauthorized settings changes due to a missing capability check in its configuration update logic. This allows unauthenticated attackers to modify core plugin settings, including organization details and registration behaviors, by exploiting exposed AJAX or admin initialization hooks.

Vulnerable Code

// File: core/admin/EE_Admin_Page.core.php (inferred location based on research plan)
// The function processes configuration updates without verifying if the user has 'manage_options' capabilities.

public function save_settings() {
    if ( isset( $_POST['ee_config'] ) ) {
        // Missing: if ( ! current_user_can( 'manage_options' ) ) { return; }
        
        $ee_config = $_POST['ee_config'];
        $this->_update_config( $ee_config );
        // ...
    }
}

---

// File: core/EE_Config.core.php (inferred location)

public static function update_configuration( $ee_config = array() ) {
    // Missing authorization check allows any execution context to update the global option
    update_option( 'ee_config', $ee_config );
}

Security Fix

--- a/core/admin/EE_Admin_Page.core.php
+++ b/core/admin/EE_Admin_Page.core.php
@@ -10,6 +10,10 @@
 	public function save_settings() {
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_die( __( 'You do not have permission to perform this action.' ) );
+		}
+		check_ajax_referer( 'ee_admin_nonce', 'ee_nonce' );
 		if ( isset( $_POST['ee_config'] ) ) {
 			$ee_config = $_POST['ee_config'];
 			$this->_update_config( $ee_config );
 		}

Exploit Outline

The exploit involves identifying a public-facing page where Event Espresso enqueues its scripts (typically a page containing the [ESPRESSO_EVENTS] shortcode) to extract a valid nonce. Once the nonce is retrieved from the localized JavaScript object (e.g., EE_JS or ee_admin_js_strings), an attacker sends an unauthenticated POST request to wp-admin/admin-ajax.php. The payload targets an action such as ee_update_config or ee_admin_ajax with an ee_ajax_action=update_config parameter. The body includes a crafted ee_config array, for example modifying ee_config[org_data][email] to an attacker-controlled address, which is then processed and saved to the database because the handler lacks a current_user_can('manage_options') check.

Check if your site is affected.

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