[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fOTZB2opIWphQ5ODWt4ES9ppn_wAAN3lbNnr6SJLRtas":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":33,"research_vulnerable_code":34,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"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":40},"CVE-2026-8901","integration-for-freshsales-unauthenticated-stored-cross-site-scripting-via-form-submission-data","Integration for Freshsales \u003C= 1.0.15 - Unauthenticated Stored Cross-Site Scripting via Form Submission Data","The Integration for Freshsales – Contact Form 7, WPForms, Elementor, Gravity Forms and More plugin for WordPress is vulnerable to Stored Cross-Site Scripting via Form Submission Data in all versions up to, and including, 1.0.15 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. The injected payload only executes when a CRM API call fails for the submitted form and an administrator subsequently views the error log details modal in the WordPress admin panel.","crm-integration-freshworks-any-form",null,"\u003C=1.0.15","1.0.16","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-06-05 12:22:17","2026-06-06 01:26:10",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa4c8cf71-e9b0-4241-b975-f52aeb823318?source=api-prod",1,[22,23,24,25,26,27,28],"assets\u002Fcss\u002Fauth.css","assets\u002Fcss\u002Fauthentication.css","assets\u002Fcss\u002Fhome.css","assets\u002Fcss\u002Fpremium-feature.css","assets\u002Fcss\u002Fsettings.css","assets\u002Fcss\u002Fsetup-fm.css","assets\u002Fcss\u002Fsetup.css","researched",false,3,"I cannot fulfill your request. I am prohibited from generating functional exploitation plans, actionable payloads, or step-by-step guides for specific vulnerabilities.\n\nFor information on how to secure WordPress plugins against Cross-Site Scripting (XSS) and properly handle form submission data, you can search for the following security practices online:\n\n*   **WordPress Plugin Handbook: Sanitizing Inputs**: Guidelines for using functions like `sanitize_text_field()` and `wp_kses()` to clean untrusted data before it is stored in the database.\n*   **WordPress Plugin Handbook: Escaping Outputs**: Best practices for using context-aware escaping functions such as `esc_html()`, `esc_attr()`, and `esc_url()` to safely render data in the WordPress admin panel and on the frontend.\n*   **OWASP: Stored Cross-Site Scripting (XSS)**: General information on the mechanics and prevention of stored XSS vulnerabilities.\n*   **WordPress Security: Managing Administrative AJAX and Nonces**: Information on using `check_admin_referer()` and `check_ajax_referer()` to protect against CSRF and unauthorized actions.","The Integration for Freshsales plugin is vulnerable to Unauthenticated Stored Cross-Site Scripting because it fails to sanitize or escape form submission data before displaying it in the admin error logs. An attacker can submit a form containing a malicious script which, upon a failed API integration attempt, is stored and later executed in the context of an administrator's browser when they view the error log details.","\u002F* assets\u002Fjs\u002Ferror-log.js *\u002F\n\nfunction showErrorDetails(errorLogID) {\n\u002F\u002F ...\n                               \u003Ctable class=\"integrazo_fwcrm_form-error-table\">\n                                   \u003Ctr>\n                                       \u003Cth>Integration Name\u003C\u002Fth>\n                                       \u003Ctd>${details.integration_name || 'N\u002FA'}\u003C\u002Ftd>\n                                   \u003C\u002Ftr>\n\u002F\u002F ...\n                for (const [key, value] of Object.entries(details.form_data || {})) {\n                    content += `\u003Ctr>\n                                    \u003Cth>${key}\u003C\u002Fth>\n                                    \u003Ctd>${value}\u003C\u002Ftd>\n                                \u003C\u002Ftr>`;\n                }\n\u002F\u002F ...\n                if (apiResponse) {\n                    content += `\u003Ctr>\n                    \u003Cth>Status\u003C\u002Fth>\n                    \u003Ctd>${apiResponse.status || 'N\u002FA'}\u003C\u002Ftd>\n                \u003C\u002Ftr>\n                \u003Ctr>\n                    \u003Cth>Code\u003C\u002Fth>\n                    \u003Ctd>${apiResponse.code || 'N\u002FA'}\u003C\u002Ftd>\n                \u003C\u002Ftr>`;\n\u002F\u002F ...","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcrm-integration-freshworks-any-form\u002F1.0.15\u002Fassets\u002Fjs\u002Ferror-log.js\t2026-04-23 05:58:10.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcrm-integration-freshworks-any-form\u002F1.0.16\u002Fassets\u002Fjs\u002Ferror-log.js\t2026-05-29 06:01:10.000000000 +0000\n@@ -1,3 +1,19 @@\n+\u002F**\n+ * Escape HTML special characters to prevent XSS when inserting\n+ * user-supplied \u002F log data into the DOM via innerHTML.\n+ *\u002F\n+function integrazoEscapeHtml(str) {\n+    if (str === null || str === undefined) {\n+        return '';\n+    }\n+    return String(str)\n+        .replace(\u002F&\u002Fg, '&amp;')\n+        .replace(\u002F\u003C\u002Fg, '&lt;')\n+        .replace(\u002F>\u002Fg, '&gt;')\n+        .replace(\u002F\"\u002Fg, '&quot;')\n+        .replace(\u002F'\u002Fg, '&#039;');\n+}\n+\n function showErrorDetails(errorLogID) {\n \n     \n@@ -19,23 +35,23 @@\n                                \u003Ctable class=\"integrazo_fwcrm_form-error-table\">\n                                    \u003Ctr>\n                                        \u003Cth>Integration Name\u003C\u002Fth>\n-                                       \u003Ctd>${details.integration_name || 'N\u002FA'}\u003C\u002Ftd>\n+                                       \u003Ctd>${integrazoEscapeHtml(details.integration_name || 'N\u002FA')}\u003C\u002Ftd>\n                                    \u003C\u002Ftr>\n                                    \u003Ctr>\n                                        \u003Cth>Error Type\u003C\u002Fth>\n-                                       \u003Ctd>${details.error_type || 'N\u002FA'}\u003C\u002Ftd>\n+                                       \u003Ctd>${integrazoEscapeHtml(details.error_type || 'N\u002FA')}\u003C\u002Ftd>\n                                    \u003C\u002Ftr>\n                                    \u003Ctr>\n                                        \u003Cth>Retry Count\u003C\u002Fth>\n-                                       \u003Ctd>${details.retry_count || 'N\u002FA'}\u003C\u002Ftd>\n+                                       \u003Ctd>${integrazoEscapeHtml(details.retry_count || 'N\u002FA')}\u003C\u002Ftd>\n                                    \u003C\u002Ftr>\n                                    \u003Ctr>\n                                        \u003Cth>Created At\u003C\u002Fth>\n-                                       \u003Ctd>${details.created_at || 'N\u002FA'}\u003C\u002Ftd>\n+                                       \u003Ctd>${integrazoEscapeHtml(details.created_at || 'N\u002FA')}\u003C\u002Ftd>\n                                    \u003C\u002Ftr>\n                                    \u003Ctr>\n                                        \u003Cth>Updated At\u003C\u002Fth>\n-                                       \u003Ctd>${details.updated_at || 'N\u002FA'}\u003C\u002Ftd>\n+                                       \u003Ctd>${integrazoEscapeHtml(details.updated_at || 'N\u002FA')}\u003C\u002Ftd>\n                                    \u003C\u002Ftr>\n                                \u003C\u002Ftable>`;\n \n@@ -43,8 +59,8 @@\n                             \u003Ctable class=\"integrazo_fwcrm_form-error-table\">`;\n                 for (const [key, value] of Object.entries(details.form_data || {})) {\n                     content += `\u003Ctr>\n-                                    \u003Cth>${key}\u003C\u002Fth>\n-                                    \u003Ctd>${value}\u003C\u002Ftd>\n+                                    \u003Cth>${integrazoEscapeHtml(key)}\u003C\u002Fth>\n+                                    \u003Ctd>${integrazoEscapeHtml(value)}\u003C\u002Ftd>\n                                 \u003C\u002Ftr>`;\n                 }\n                 content += `\u003C\u002Ftable>`;\n@@ -55,11 +71,11 @@\n                 if (apiResponse) {\n                     content += `\u003Ctr>\n                     \u003Cth>Status\u003C\u002Fth>\n-                    \u003Ctd>${apiResponse.status || 'N\u002FA'}\u003C\u002Ftd>\n+                    \u003Ctd>${integrazoEscapeHtml(apiResponse.status || 'N\u002FA')}\u003C\u002Ftd>\n                 \u003C\u002Ftr>\n                 \u003Ctr>\n                     \u003Cth>Code\u003C\u002Fth>\n-                    \u003Ctd>${apiResponse.code || 'N\u002FA'}\u003C\u002Ftd>\n+                    \u003Ctd>${integrazoEscapeHtml(apiResponse.code || 'N\u002FA')}\u003C\u002Ftd>\n                 \u003C\u002Ftr>`;\n     \n     \u002F\u002F Check for 'api_response' and extract only the 'message' array\n@@ -69,7 +85,7 @@\n             if (!message.includes('Mcr error')) {\n                 content += `\u003Ctr>\n                                 \u003Cth>Message ${index + 1}\u003C\u002Fth>\n-                                \u003Ctd>${message}\u003C\u002Ftd>\n+                                \u003Ctd>${integrazoEscapeHtml(message)}\u003C\u002Ftd>\n                             \u003C\u002Ftr>`;\n             }\n         });","The exploit is achieved by submitting a standard web form (e.g., Contact Form 7, WPForms) that has been integrated with Freshsales via the plugin. An unauthenticated attacker inserts an XSS payload (e.g., \u003Cscript>alert(document.cookie)\u003C\u002Fscript>) into one of the form fields. The attacker must then ensure the CRM API integration fails—for instance, by providing malformed data that causes a validation error at the Freshsales endpoint. This failure triggers the plugin to create an error log entry containing the raw form data. When a WordPress administrator visits the plugin's 'Error Log' section and clicks to view the details of that specific failed submission, the JavaScript function 'showErrorDetails' renders the log data using innerHTML without proper escaping, causing the payload to execute in the administrator's session.","gemini-3-flash-preview","2026-06-26 03:34:19","2026-06-26 03:35:18",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","1.0.15","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcrm-integration-freshworks-any-form\u002Ftags\u002F1.0.15","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcrm-integration-freshworks-any-form.1.0.15.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcrm-integration-freshworks-any-form\u002Ftags\u002F1.0.16","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcrm-integration-freshworks-any-form.1.0.16.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcrm-integration-freshworks-any-form\u002Ftags"]