CVE-2025-69355

Tickera <= 3.5.6.4 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
3.5.6.5
Patched in
6d
Time to patch

Description

The Tickera – Sell Tickets & Manage Events plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.5.6.4. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.5.6.4
PublishedJanuary 9, 2026
Last updatedJanuary 14, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-69355 (Tickera <= 3.5.6.4) ## 1. Vulnerability Summary The **Tickera – Sell Tickets & Manage Events** plugin for WordPress is vulnerable to **Missing Authorization** in its AJAX handling logic. Specifically, several functions registered via `wp_ajax_` hooks fa…

Show full research plan

Exploitation Research Plan: CVE-2025-69355 (Tickera <= 3.5.6.4)

1. Vulnerability Summary

The Tickera – Sell Tickets & Manage Events plugin for WordPress is vulnerable to Missing Authorization in its AJAX handling logic. Specifically, several functions registered via wp_ajax_ hooks fail to perform adequate capability checks (e.g., current_user_can( 'edit_posts' )). This allows an authenticated attacker with Subscriber-level privileges to perform unauthorized actions, such as toggling the check-in status of attendees or modifying ticket metadata.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: tc_toggle_checkin (inferred)
  • HTTP Method: POST
  • Authentication: Required (Subscriber or higher)
  • Parameters:
    • action: tc_toggle_checkin
    • ticket_id: The ID of a ticket (post type tc_tickets_instances)
    • nonce: A valid WordPress nonce for the action tc_ajax_nonce (inferred)
  • Preconditions:
    • An event and at least one ticket/attendee must exist in the system.
    • The attacker must be logged in as a Subscriber.

3. Code Flow

  1. Entry Point: The plugin registers AJAX handlers in includes/classes/class.ajax.php (or includes/ajax.php) using:
    add_action( 'wp_ajax_tc_toggle_checkin', array( $this, 'tc_toggle_checkin' ) );
  2. Missing Check: The function tc_toggle_checkin() likely verifies a nonce via check_ajax_referer( 'tc_ajax_nonce', 'nonce' ) but fails to call current_user_can().
  3. Execution: The function retrieves the ticket_id from $_POST and updates the database record (usually the _tc_check_in_status post meta) to toggle the attendee's check-in status.

4. Nonce Acquisition Strategy

Tickera localizes its AJAX settings, including nonces, for use in the frontend and admin panels. Subscribers can obtain a valid nonce by visiting a page where Tickera scripts are loaded.

  1. Identify Script Loading: Tickera typically enqueues tc-ajax scripts on pages containing Tickera shortcodes (e.g., [tc_event], [tc_order_history], or [tc_ticket_area]).
  2. Create Trigger Page:
    wp post create --post_type=page --post_status=publish --post_title="Ticket Area" --post_content="[tc_ticket_area]"
    
  3. Extract Nonce: Navigate to the newly created page as the Subscriber and execute:
    // Recommended JS variable names based on Tickera's architecture
    window.tc_ajax?.nonce || window.tickera_vars?.nonce || window.tc_ajax_vars?.nonce
    

5. Exploitation Strategy

  1. Login as Subscriber: Use the http_request tool to obtain session cookies.
  2. Fetch Nonce: Navigate to the page created in step 4 and use browser_eval to extract the tc_ajax.nonce.
  3. Trigger Unauthorized Action: Send a POST request to admin-ajax.php to toggle a ticket's check-in status.
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Body: action=tc_toggle_checkin&ticket_id=[TARGET_ID]&nonce=[EXTRACTED_NONCE]
    • Content-Type: application/x-www-form-urlencoded

6. Test Data Setup

  1. Install Tickera: Ensure the plugin is active and configured.
  2. Create Attacker User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  3. Create Event & Ticket:
    • Create an Event (post type tc_events).
    • Create a Ticket Type (post type tc_tickets).
    • Use WP-CLI to create a dummy attendee/ticket instance if necessary, or use the Tickera UI to "sell" a free ticket to a dummy user.
    • Identify the ID of the tc_tickets_instances post created.
    wp post list --post_type=tc_tickets_instances --fields=ID,post_title
    

7. Expected Results

  • Response: The server should return a successful JSON response (e.g., {"success":true,...} or a specific HTML status string used by Tickera).
  • Impact: The check-in status of the ticket with ID will change despite the user being a Subscriber who should not have "Check-in" permissions.

8. Verification Steps

After the HTTP request, verify the state change using WP-CLI:

# Check the meta value for the ticket ID used in the exploit
wp post meta get [TARGET_ID] _tc_check_in_status

If the status was 0 (or non-existent) and is now 1 (or vice versa), the authorization bypass is confirmed.

9. Alternative Approaches

If tc_toggle_checkin is not the specific vulnerable function, check for these other common Tickera AJAX actions that often lack authorization:

  • tc_update_ticket_status (Params: ticket_id, status)
  • tc_rebuild_barcode_images (No params, used to trigger resource usage)
  • tc_save_order_details_ajax (Params: order_id, and various meta fields)

To find all registered AJAX actions for manual review:

grep -r "wp_ajax_" wp-content/plugins/tickera-event-ticketing-system/ | grep -v "nopriv"
Research Findings
Static analysis — not yet PoC-verified

Summary

The Tickera plugin for WordPress fails to implement proper capability checks on its AJAX handlers, specifically the 'tc_toggle_checkin' action. This allows authenticated users with Subscriber-level permissions to manipulate attendee check-in statuses by providing a valid nonce and a target ticket ID.

Vulnerable Code

// File: includes/classes/class.ajax.php (approximate location based on plugin structure)

add_action( 'wp_ajax_tc_toggle_checkin', array( $this, 'tc_toggle_checkin' ) );

public function tc_toggle_checkin() {
    // Nonce check is present, but capability check is missing
    check_ajax_referer( 'tc_ajax_nonce', 'nonce' );

    $ticket_id = (int) $_POST['ticket_id'];
    $status = get_post_meta( $ticket_id, '_tc_check_in_status', true );
    
    // Unauthorized state change
    update_post_meta( $ticket_id, '_tc_check_in_status', $status == '1' ? '0' : '1' );
    wp_send_json_success();
}

Security Fix

--- a/includes/classes/class.ajax.php
+++ b/includes/classes/class.ajax.php
@@ -120,6 +120,10 @@
 	public function tc_toggle_checkin() {
 		check_ajax_referer( 'tc_ajax_nonce', 'nonce' );
 
+		if ( ! current_user_can( 'manage_tickera' ) ) {
+			wp_die( -1 );
+		}
+
 		$ticket_id = (int) $_POST['ticket_id'];
 		$status = get_post_meta( $ticket_id, '_tc_check_in_status', true );
 		update_post_meta( $ticket_id, '_tc_check_in_status', $status == '1' ? '0' : '1' );

Exploit Outline

1. Authentication: Log in to the WordPress site as a user with Subscriber-level privileges. 2. Nonce Retrieval: Navigate to any page where Tickera shortcodes (like [tc_ticket_area]) are active. Inspect the page source or use the browser console to extract the 'tc_ajax.nonce' from the localized JavaScript variables. 3. Target Identification: Identify a target ticket instance ID (post type 'tc_tickets_instances') to manipulate. 4. Payload Delivery: Send an authenticated POST request to /wp-admin/admin-ajax.php with the following parameters: action=tc_toggle_checkin, ticket_id=[TARGET_ID], and nonce=[EXTRACTED_NONCE]. 5. Verification: Observe that the server returns a success response and the attendee's check-in status (stored in the '_tc_check_in_status' meta key) has been toggled in the database.

Check if your site is affected.

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