CVE-2026-57705

Event Tickets and Registration <= 5.28.5 - Missing Authorization

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

Description

The Event Tickets and Registration plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 5.28.5. 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<=5.28.5
PublishedJuly 8, 2026
Last updatedJuly 14, 2026
Affected pluginevent-tickets

What Changed in the Fix

Changes introduced in v5.28.5.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-57705 ## 1. Vulnerability Summary The **Event Tickets and Registration** plugin (<= 5.28.5) contains a **Missing Authorization** vulnerability in its Stripe diagnostic functionality. Specifically, the function responsible for testing Stripe payment method con…

Show full research plan

Exploitation Research Plan - CVE-2026-57705

1. Vulnerability Summary

The Event Tickets and Registration plugin (<= 5.28.5) contains a Missing Authorization vulnerability in its Stripe diagnostic functionality. Specifically, the function responsible for testing Stripe payment method configurations (likely test_connection or similar) fails to perform a capability check (e.g., current_user_can( 'manage_options' )).

This allows an unauthenticated attacker to trigger the TEC\Tickets\Commerce\Gateways\Stripe\Payment_Intent::test_creation method. This method initiates a live API request to Stripe to create and then immediately cancel a "Validation Test" Payment Intent. While the intents are cancelled, an attacker can abuse this to interact with the merchant's Stripe account, potentially exhausting API rate limits or cluttering logs with unauthorized diagnostic requests.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: tec_tickets_commerce_stripe_test_connection (inferred based on namespace TEC\Tickets\Commerce... and common diagnostic patterns) or tribe_tickets_commerce_stripe_test_connection.
  • Parameter: payment_methods[] (array of Stripe payment method strings).
  • Authentication: None required (unauthenticated).
  • Preconditions: The "Tickets Commerce" feature must be active with the "Stripe" gateway selected, although the
Research Findings
Static analysis — not yet PoC-verified

Summary

The Event Tickets and Registration plugin for WordPress fails to validate that a client-supplied Stripe Payment Intent matches the expected order amount during the checkout process. This allows unauthenticated attackers to fulfill high-value ticket orders by providing a Payment Intent ID associated with a significantly lower-value transaction.

Vulnerable Code

// src/Tickets/Commerce/Gateways/Stripe/Payment_Intent_Handler.php

public function update_payment_intent( $data, \WP_Post $order ) {
    $body = [];

    // Attempt to avoid an extra request by using the existing payment intent.
    $payment_intent = $this->get();

    if ( empty( $payment_intent['id'] ) || empty( $data['payment_intent']['id'] ) || $data['payment_intent']['id'] !== $payment_intent['id'] ) {
        $payment_intent = Payment_Intent::get( $data['payment_intent']['id'] );
    }

    // Missing validation to ensure payment_intent amount matches cart/order total before proceeding

    $stripe_receipt_emails = tribe_get_option( Settings::$option_stripe_receipt_emails );
    $body['metadata']      = $this->get_updated_metadata( $order, $payment_intent );

---

// src/Tickets/Commerce/Gateways/Stripe/REST/Order_Endpoint.php

// Logic within the order fulfillment endpoint
if ( ! isset( $payment_intent['id'] ) && ! empty( $payment_intent['errors'] ) ) {
    return new WP_Error( 'tec-tc-gateway-stripe-failed-getting-payment-intent', $messages['failed-getting-payment-intent'], $order );
}

// Missing check here to confirm Payment Intent amount matches order total

$status = tribe( Status::class )->convert_payment_intent_to_commerce_status( $payment_intent );

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.28.5/src/Tickets/Commerce/Gateways/Stripe/Payment_Intent_Handler.php /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.28.5.1/src/Tickets/Commerce/Gateways/Stripe/Payment_Intent_Handler.php
--- /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.28.5/src/Tickets/Commerce/Gateways/Stripe/Payment_Intent_Handler.php	2026-06-19 14:54:50.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.28.5.1/src/Tickets/Commerce/Gateways/Stripe/Payment_Intent_Handler.php	2026-06-29 14:48:00.000000000 +0000
@@ -223,6 +225,26 @@
 			$payment_intent = Payment_Intent::get( $data['payment_intent']['id'] );
 		}
 
+		if ( is_wp_error( $payment_intent ) || ! is_array( $payment_intent ) || empty( $payment_intent['id'] ) ) {
+			return new WP_Error(
+				'tec-tc-gateway-stripe-payment-intent-invalid',
+				__( 'The payment could not be verified. Please refresh checkout and try again.', 'event-tickets' )
+			);
+		}
+
+		/*
+		 * Security: the Payment Intent ID is supplied by the client, so confirm it matches the
+		 * current cart before binding it to this order. Without this a Payment Intent created for
+		 * a different (e.g. lower-value) cart could be attached here and later used to complete the
+		 * order after paying the smaller amount.
+		 */
+		if ( ! Payment_Intent::is_valid_for_cart( $payment_intent, tribe( Cart::class ) ) ) {
+			return new WP_Error(
+				'tec-tc-gateway-stripe-payment-intent-cart-mismatch',
+				__( 'The selected payment does not match the items in your cart. Please refresh checkout and try again.', 'event-tickets' )
+			);
+		}
+
 		$stripe_receipt_emails = tribe_get_option( Settings::$option_stripe_receipt_emails );
 		$body['metadata']      = $this->get_updated_metadata( $order, $payment_intent );

Exploit Outline

The exploit targets the Stripe checkout flow of the Tickets Commerce feature. 1. An attacker identifies a high-priced ticket (e.g., $1000) and adds it to their cart. 2. In a separate browser session or using a direct API call to Stripe, the attacker creates a Payment Intent for a minimal amount (e.g., $1) using the merchant's publishable key (or simply by starting a checkout for a $1 item elsewhere on the site). 3. During the finalization of the $1000 ticket purchase, the attacker intercepts the client-side request to the WordPress REST API (likely the Order_Endpoint) or the AJAX handler for `update_payment_intent`. 4. The attacker replaces the legitimate Payment Intent ID for the $1000 transaction with the Payment Intent ID for the $1 transaction. 5. Because the plugin lacked server-side verification of the Payment Intent's 'amount' field against the actual order total, it would accept the low-value payment as valid for the high-value order and mark the tickets as fully paid upon webhook receipt or REST confirmation.

Check if your site is affected.

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