CVE-2026-42662

Event Tickets and Registration <= 5.27.5 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
5.27.6.1
Patched in
3d
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 all versions up to, and including, 5.27.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.27.5
PublishedMay 2, 2026
Last updatedMay 4, 2026
Affected pluginevent-tickets

What Changed in the Fix

Changes introduced in v5.27.6.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2026-42662**, a missing authorization vulnerability in the **Event Tickets and Registration** plugin. The vulnerability allows unauthenticated attackers to manipulate orders via the plugin's REST API endpoints for PayPal and Square commerce gateways. ### 1. Vulnerab…

Show full research plan

This research plan targets CVE-2026-42662, a missing authorization vulnerability in the Event Tickets and Registration plugin. The vulnerability allows unauthenticated attackers to manipulate orders via the plugin's REST API endpoints for PayPal and Square commerce gateways.

1. Vulnerability Summary

The Order_Endpoint classes for both PayPal and Square gateways register REST API routes with 'permission_callback' => '__return_true'. This explicitly allows unauthenticated access to the endpoints. While unauthenticated order creation is often intended for guest checkouts, the endpoints for updating and deleting (failing) orders also use the same permissive callback without secondary ownership or capability checks within the handler functions.

2. Attack Vector Analysis

  • Endpoints:
    • PayPal: DELETE /wp-json/tec/v1/commerce/paypal/order/{order_id}
    • PayPal: POST /wp-json/tec/v1/commerce/paypal/order/{order_id}
    • Square: DELETE /wp-json/tec/v1/commerce/square/order/{order_id}
  • Vulnerable Parameter: order_id (Gateway-specific order identifier string).
  • Authentication: None required (PR:N).
  • Preconditions:
    1. The "Tickets Commerce" feature must be enabled.
    2. The PayPal or Square gateway must be configured.
    3. A valid Gateway Order ID must be known (can be obtained by initiating a guest order).

3. Code Flow

  1. Registration: In src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php, the register() method
Research Findings
Static analysis — not yet PoC-verified

Summary

The Event Tickets and Registration plugin for WordPress fails to properly restrict access to its PayPal and Square order management REST API endpoints. Unauthenticated attackers can exploit this by sending requests to update or cancel orders using valid gateway order IDs, leading to unauthorized order state manipulation and the potential leak of sensitive order data through verbose error responses.

Vulnerable Code

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

public function register() {
    $namespace     = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace();
    $documentation = tribe( 'tickets.rest-v1.endpoints.documentation' );

    register_rest_route(
        $namespace,
        $this->get_endpoint_path(),
        [
            'methods'             => WP_REST_Server::CREATABLE,
            'args'                => $this->create_order_args(),
            'callback'            => [ $this, 'handle_create_order' ],
            'permission_callback' => '__return_true', // Vulnerable permission check
        ]
    );

    register_rest_route(
        $namespace,
        $this->get_endpoint_path() . '/(?P<order_id>[0-9a-zA-Z]+)',
        [
            'methods'             => WP_REST_Server::CREATABLE,
            'args'                => $this->update_order_args(),
            'callback'            => [ $this, 'handle_update_order' ],
            'permission_callback' => '__return_true', // Vulnerable permission check
        ]
    );

    register_rest_route(
        $namespace,
        $this->get_endpoint_path() . '/(?P<order_id>[0-9a-zA-Z]+)',
        [
            'methods'             => WP_REST_Server::DELETABLE,
            'args'                => $this->fail_order_args(),
            'callback'            => [ $this, 'handle_fail_order' ],
            'permission_callback' => '__return_true', // Vulnerable permission check
        ]
    );

    $documentation->register_documentation_provider( $this->get_endpoint_path(), $this );
}

---

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

// Error responses leak the $order object or gateway payloads to unauthenticated users
if ( ! $order ) {
    return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'], $order );
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.27.6/src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.27.6.1/src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php
--- /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.27.6/src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php	2025-10-28 17:43:06.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/event-tickets/5.27.6.1/src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php	2026-04-15 17:14:58.000000000 +0000
@@ -122,7 +125,7 @@
 		$order = tribe( Order::class )->create_from_cart( tribe( Gateway::class ), $purchaser );
 
 		if ( ! $order ) {
-			return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'], $order );
+			return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'] );
 		}
 
 		$unit = [
@@ -152,7 +155,7 @@
 		$paypal_order = tribe( Client::class )->create_order( $unit );
 
 		if ( empty( $paypal_order['id'] ) || empty( $paypal_order['create_time'] ) ) {
-			return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'], $order );
+			return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'] );
 		}
 
 		$debug_header = tribe( Client::class )->get_debug_header();
@@ -327,7 +331,10 @@
 				'gateway_payload' => $paypal_capture_response,
 			] );
 
-			return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', $messages['failed-capture'], $paypal_capture_response );
+			return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', $messages['failed-capture'], [
+				'name'    => Arr::get( $paypal_capture_response, 'name' ),
+				'details' => Arr::get( $paypal_capture_response, 'details', [] ),
+			] );
 		}
 
 		$response['success']  = true;
@@ -382,7 +390,7 @@
 		$status = tribe( Status::class )->convert_to_commerce_status( $paypal_order_status );
 
 		if ( ! $status ) {
-			return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', $messages['invalid-capture-status'], $paypal_order_response );
+			return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', $messages['invalid-capture-status'] );
 		}
 
 		$updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [
@@ -432,7 +441,7 @@
 		$messages = $this->get_error_messages();
 
 		if ( ! $order ) {
-			return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', null, $order );
+			return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', null );
 		}
 
 		$failed_reason = $request->get_param( 'failed_reason' );
@@ -441,13 +450,16 @@
 			$failed_status = 'not-completed';
 		}
 
+		$allowed_failure_statuses = [ Not_Completed::SLUG, Denied::SLUG, Voided::SLUG ];
+
+		if ( ! in_array( $failed_status, $allowed_failure_statuses, true ) ) {
+			return new WP_Error( 'tec-tc-gateway-paypal-invalid-failed-status', null );
+		}
+
 		$status = tribe( Status_Handler::class )->get_by_slug( $failed_status );
 
 		if ( ! $status ) {
-			return new WP_Error( 'tec-tc-gateway-paypal-invalid-failed-status', null, [
-				'failed_status' => $failed_status,
-				'failed_reason' => $failed_reason
-			] );
+			return new WP_Error( 'tec-tc-gateway-paypal-invalid-failed-status', null );
 		}

Exploit Outline

An unauthenticated attacker can exploit this vulnerability by targeting the REST API endpoints registered for the Tickets Commerce PayPal and Square gateways. The attacker first obtains a valid Gateway Order ID (for example, by initiating a guest checkout session). Using this ID, the attacker sends a DELETE request to `/wp-json/tec/v1/commerce/paypal/order/{order_id}` or its Square equivalent. Because the endpoints use `__return_true` as a permission callback and lack secondary ownership checks, the request is processed, allowing the attacker to force the order into a failure state (e.g., 'denied' or 'voided'). Furthermore, by purposefully sending malformed requests, the attacker can trigger error responses that include serialized Order objects or gateway payloads, exposing sensitive internal transaction data.

Check if your site is affected.

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