CVE-2026-54830

Five Star Restaurant Reservations – WordPress Booking Plugin <= 2.7.19 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
2.7.20
Patched in
7d
Time to patch

Description

The Five Star Restaurant Reservations – WordPress Booking Plugin 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.19. 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.19
PublishedJune 17, 2026
Last updatedJune 23, 2026

What Changed in the Fix

Changes introduced in v2.7.20

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill this request. I am prohibited from generating actionable exploitation material, functional payloads, or detailed research plans for the exploitation of specific vulnerabilities in software or code snippets. For information on identifying and remediating authorization issues in Wor…

Show full research plan

I cannot fulfill this request. I am prohibited from generating actionable exploitation material, functional payloads, or detailed research plans for the exploitation of specific vulnerabilities in software or code snippets.

For information on identifying and remediating authorization issues in WordPress, I recommend consulting the WordPress Plugin Handbook on Security and searching for resources on "WordPress AJAX security best practices" and "Proper capability checks in WordPress plugins." These resources provide guidance on implementing current_user_can() and using nonces correctly to protect sensitive functions.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Five Star Restaurant Reservations plugin for WordPress is vulnerable to unauthorized payment confirmation due to insufficient verification in its Stripe payment processing logic. Unauthenticated attackers can exploit this to mark reservations as paid without actually completing a transaction by spoofing the payment success callback.

Vulnerable Code

// includes/PaymentGatewayStripe.class.php lines 23-24
add_action( 'wp_ajax_rtb_stripe_pmt_succeed', array( $this, 'stripe_sca_succeed' ) );
add_action( 'wp_ajax_nopriv_rtb_stripe_pmt_succeed', array( $this, 'stripe_sca_succeed' ) );

---

// includes/PaymentGatewayStripe.class.php lines 458-460
public function valid_payment( $booking ) {

  return ! empty( $booking->stripe_payment_intent_id ) && sanitize_text_field( $_POST['payment_id'] ) === $booking->stripe_payment_intent_id;
}

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/restaurant-reservations/2.7.19/includes/PaymentGatewayStripe.class.php	2026-04-29 19:23:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/restaurant-reservations/2.7.20/includes/PaymentGatewayStripe.class.php	2026-06-03 13:51:22.000000000 +0000
@@ -449,13 +458,48 @@
   }
 
   /**
-   * Validate the payment success request by verifing the payment_intent ID
+   * Validate the payment success request by verifying the payment_intent ID
    * 
-   * @return bool true on valid else false
+   * @param  rtbBooking $booking
+   * @return bool true if Stripe confirms payment else false
    */
   public function valid_payment( $booking ) {
+	global $rtb_controller;
+
+	// Must have an intent ID stored server-side from the intent-creation step
+	if ( empty( $booking->stripe_payment_intent_id ) ) { return false; }
+
+	// The posted payment_id must match what we stored
+	$posted_id = sanitize_text_field( $_POST['payment_id'] ?? '' );
+	if ( $posted_id !== $booking->stripe_payment_intent_id ) { return false; }
+
+	// Ask Stripe if the intent was actually paid
+	try {
+
+	  // load the stripe libraries
+	  require_once( RTB_PLUGIN_DIR . '/lib/stripe/init.php' );
+  
+	  \rtbStripe\Stripe::setApiKey( $this->get_secret() );
 
-    return ! empty( $booking->stripe_payment_intent_id ) && sanitize_text_field( $_POST['payment_id'] ) === $booking->stripe_payment_intent_id;
+	  $intent = \rtbStripe\PaymentIntent::retrieve( $booking->stripe_payment_intent_id );
+
+	  $is_hold = $rtb_controller->settings->get_setting( 'rtb-stripe-hold' );
+
+	  // For normal payments: status must be 'succeeded'
+	  // For hold/manual-capture: status must be 'requires_capture'
+	  $valid_status = $is_hold ? 'requires_capture' : 'succeeded';
+
+	  return $intent->status === $valid_status;
+	}
+	catch ( Exception $ex ) {
+
+	  if ( defined('WP_DEBUG') && WP_DEBUG ) {
+
+		error_log( sprintf( __( 'Five Star RTB Stripe valid_payment error: %s', 'restaurant-reservations' ), $ex->getMessage() ) );
+	  }
+
+	  return false;
+	}
   }

Exploit Outline

The exploit targets the AJAX endpoint used for handling successful Stripe SCA (Strong Customer Authentication) payments. 1. The attacker identifies a valid `booking_id` (typically generated during the initial reservation step). 2. The attacker sends an unauthenticated POST request to `/wp-admin/admin-ajax.php` with the action `rtb_stripe_pmt_succeed`. 3. The payload includes the `booking_id` and a `payment_id` that matches the `stripe_payment_intent_id` associated with that booking (which might be known from previous client-side interactions). 4. In the vulnerable version, the `valid_payment` function only performs a loose string comparison between the provided `payment_id` and the one stored in the booking object. It does not communicate with Stripe's API to confirm the payment's actual status. 5. Consequently, the reservation is processed and confirmed by the system as if a successful payment had occurred, allowing the attacker to bypass the deposit or payment requirement.

Check if your site is affected.

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