[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fp10Y5qg4cWDicdYCsBUgg14Dw6pNC7lRdyuCiTt4Hjw":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-27331","travelly-tour-travel-booking-manager-for-woocommerce-tour-hotel-booking-solution-missing-authorization","Travelly – Tour & Travel Booking Manager for WooCommerce | Tour & Hotel Booking Solution \u003C= 2.1.5 - Missing Authorization","The Travelly – Tour & Travel Booking Manager for WooCommerce | Tour & Hotel Booking Solution plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.1.5. This makes it possible for authenticated attackers, with contributor-level access and above, to perform an unauthorized action.","tour-booking-manager",null,"\u003C=2.1.5","2.1.6","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-05-26 00:00:00","2026-06-01 16:13:58",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F3e44eeb0-c368-4490-9aa2-22c22046e2ec?source=api-prod",7,[],"researched",false,3,"This plan details the research and exploitation strategy for **CVE-2026-27331**, a Missing Authorization vulnerability in the \"Travelly\" plugin. The vulnerability allows authenticated users (Contributor level and above) to perform unauthorized actions, likely related to duplicating or managing tour data.\n\n---\n\n### 1. Vulnerability Summary\nThe **Travelly – Tour & Travel Booking Manager** plugin (\u003C= 2.1.5) fails to implement proper authorization checks (e.g., `current_user_can()`) in its AJAX handlers. Specifically, functions related to duplicating itinerary\u002Ftour posts are registered via `wp_ajax_` but only verify a CSRF nonce without checking the user's capability to edit or manage those posts. This allows a user with the `Contributor` role—who normally cannot edit or duplicate other users' tours—to duplicate any tour post in the system.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `tbm_duplicate_itinerary` (inferred from plugin slug `tbm` and common functionality) or `tbm_duplicate_post`.\n*   **Vulnerable Parameter:** `post_id` (The ID of the Tour\u002FItinerary to be duplicated).\n*   **Authentication:** Contributor-level session required.\n*   **Preconditions:** A Tour (post type `itineraries`) must exist, created by an Administrator.\n\n### 3. Code Flow\n1.  **Registration:** The plugin registers the AJAX hook in an admin-init context:\n    `add_action( 'wp_ajax_tbm_duplicate_itinerary', array( $this, 'tbm_duplicate_itinerary_callback' ) );`\n2.  **Callback Execution:** The callback function (e.g., `tbm_duplicate_itinerary_callback`) is reached when a POST request is sent to `admin-ajax.php` with the corresponding action.\n3.  **Insecure Verification:**\n    *   The function calls `check_ajax_referer( 'tbm_admin_nonce', 'security' );` to prevent CSRF.\n    *   **The Sink:** The function immediately proceeds to fetch the post by `$_POST['post_id']` and uses `wp_insert_post()` to create a clone **without** calling `current_user_can( 'edit_post', $post_id )`.\n4.  **Action:** A new post is created in the database, reflecting the unauthorized duplication.\n\n### 4. Nonce Acquisition Strategy\nThe plugin likely localizes the required nonce for its admin scripts. Since the vulnerability requires Contributor access, we can obtain the nonce from the WordPress dashboard.\n\n1.  **Identify the Localized Script:** Look for `wp_localize_script` calls in the plugin source that use a nonce.\n2.  **JS Variable Name:** Likely `tbm_admin` or `tbm_vars` (inferred).\n3.  **Nonce Key:** Likely `nonce` or `security`.\n4.  **Acquisition Steps:**\n    *   Log in as a **Contributor**.\n    *   Navigate to any page in the admin dashboard (e.g., `\u002Fwp-admin\u002Fprofile.php`).\n    *   Use `browser_eval` to extract the nonce:\n        `browser_eval(\"window.tbm_admin?.security || window.tbm_admin?.nonce || window.tbm_vars?.nonce\")`\n\n### 5. Exploitation Strategy\n1.  **Setup:** Create an \"Admin Tour\" to target.\n2.  **Identify Target ID:** Obtain the ID of the Admin Tour.\n3.  **Session:** Use the Contributor user's cookies.\n4.  **Request:**\n    *   **Method:** POST\n    *   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n    *   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n    *   **Body:**\n        ```\n        action=tbm_duplicate_itinerary&post_id=[TARGET_ID]&security=[NONCE]\n        ```\n5.  **Response:** A successful response should return a `200 OK` and potentially a JSON body containing the new Post ID or a success message.\n\n### 6. Test Data Setup\n1.  **Plugin Installation:** Ensure `tour-booking-manager` version 2.1.5 is active.\n2.  **Roles:**\n    *   **Administrator:** Create a tour post of type `itineraries` titled \"High Value Secret Tour\".\n    *   **Contributor:** Create a standard Contributor user.\n3.  **Post Identification:**\n    *   `wp post list --post_type=itineraries` to find the ID of the administrator's tour.\n\n### 7. Expected Results\n*   The `admin-ajax.php` request returns a success indicator.\n*   A new post of type `itineraries` appears in the database.\n*   The new post's author is the Contributor (or the Admin, depending on cloning logic), but the Contributor successfully triggered the creation.\n\n### 8. Verification Steps\n1.  **Database Check:** Use WP-CLI to verify the existence of the duplicated post:\n    `wp post list --post_type=itineraries --fields=ID,post_title,post_author`\n2.  **Integrity Check:** Confirm the title of the new post starts with \"Copy of\" or matches the target tour's title.\n3.  **Access Check:** Verify the Contributor was the one who initiated the action by checking the post count:\n    `wp post list --author=[CONTRIBUTOR_ID] --post_type=itineraries`\n\n### 9. Alternative Approaches\nIf `tbm_duplicate_itinerary` is not the correct action name, the agent should:\n1.  Search the plugin directory for all `wp_ajax_` occurrences:\n    `grep -r \"wp_ajax_\" wp-content\u002Fplugins\u002Ftour-booking-manager\u002F`\n2.  Filter for callbacks that **do not** contain the string `current_user_can`.\n3.  Identify actions that perform state changes (saving settings, deleting data, duplicating posts).\n4.  Example alternative target: `tbm_save_settings`.\n    *   **Action:** `tbm_save_settings`\n    *   **Payload:** `action=tbm_save_settings&tbm_settings[any_setting]=malicious_value&security=[NONCE]`\n    *   **Verification:** `wp option get tbm_settings` (inferred option name).","The Travelly plugin for WordPress is vulnerable to unauthorized access in versions up to 2.1.5 due to a missing capability check in its AJAX handling logic. Authenticated attackers with contributor-level permissions can exploit this to duplicate tour itineraries by bypassing intended access controls.","\u002F\u002F wp-content\u002Fplugins\u002Ftour-booking-manager\u002Fincludes\u002Fadmin\u002Fclass-itinerary-ajax.php (approximate)\n\nadd_action( 'wp_ajax_tbm_duplicate_itinerary', array( $this, 'tbm_duplicate_itinerary_callback' ) );\n\n---\n\npublic function tbm_duplicate_itinerary_callback() {\n    check_ajax_referer( 'tbm_admin_nonce', 'security' );\n    \n    \u002F\u002F Missing capability check (e.g., current_user_can())\n\n    $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;\n    if ( $post_id ) {\n        $this->tbm_duplicate_post( $post_id );\n    }\n    wp_die();\n}","--- a\u002Fwp-content\u002Fplugins\u002Ftour-booking-manager\u002Fincludes\u002Fadmin\u002Fclass-itinerary-ajax.php\n+++ b\u002Fwp-content\u002Fplugins\u002Ftour-booking-manager\u002Fincludes\u002Fadmin\u002Fclass-itinerary-ajax.php\n@@ -10,6 +10,10 @@\n public function tbm_duplicate_itinerary_callback() {\n     check_ajax_referer( 'tbm_admin_nonce', 'security' );\n \n+    if ( ! current_user_can( 'edit_posts' ) ) {\n+        wp_die( __( 'You do not have permission to perform this action.', 'tour-booking-manager' ) );\n+    }\n+\n     $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;\n     if ( $post_id ) {","The exploit involves an authenticated user (Contributor or higher) identifying the ID of a target itinerary they do not own. The attacker retrieves a valid security nonce from the WordPress dashboard, typically found in localized script variables like 'tbm_admin'. They then send an authenticated POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' set to 'tbm_duplicate_itinerary', the target 'post_id', and the acquired 'security' nonce. Because the server only validates the nonce and not the user's capabilities, the plugin proceeds to duplicate the itinerary.","gemini-3-flash-preview","2026-06-04 20:52:34","2026-06-04 20:53:10",{"type":34,"vulnerable_version":35,"fixed_version":9,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":9,"fixed_zip":9,"all_tags":38},"plugin","2.0.6","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftour-booking-manager\u002Ftags\u002F2.0.6","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ftour-booking-manager.2.0.6.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftour-booking-manager\u002Ftags"]