Persistent Cross-Site Scripting (XSS) Vulnerability in Traffic Manager
Our Plugin Vulnerabilities Firewall blocked an attempt to exploit a vulnerability we traced back to the plugin Traffic Manager. The plugin was closed on the WordPress Plugin Directory in September 2022 for a claimed security issue. No details were provided. Based on the timing of the closure and public claims about vulnerabilities in the plugin, that would appear to be related to a different security vulnerability than the hacker was trying to exploit. This security issue they were trying to exploit is a persistent cross-site scripting (XSS) vulnerability.
The details provided with the block show that an AJAX request was made with the action used UserWebStat. And the value of a POST input “page” sent with the request was a script tag. Traffic Manager makes the function UserWebStat() in the file /traffic-manager.php accessible through an AJAX request with that action for those logged in to WordPress as well those not logged in:
58 59 | add_action( 'wp_ajax_UserWebStat', array( $this, 'UserWebStat')); add_action( 'wp_ajax_nopriv_UserWebStat', array( $this, 'UserWebStat')); |
The function sets the value of that POST input “page” to the variable $page:
2745 2746 2747 2748 2749 2750 2751 2752 2753 | function UserWebStat() { global $wpdb ; $wpdb->show_errors(); // Retrieve Information and Parameters $browserUserAgent = esc_sql($_POST['browserUserAgent']) ; $cookieEnabled = esc_sql($_POST['cookieEnabled']) ; $referer = esc_sql($_POST['referer']) ; $page = esc_sql($_POST['page']) ; |
It then saves the value in a database entry:
2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 | $sql_insert = "INSERT INTO ".$this->table_name." SET " ; $sql_insert .= "type='single', " ; $sql_insert .= "count=1, " ; $sql_insert .= "uniq_visit=".$unique.", " ; $sql_insert .= "viewed=FALSE, " ; $sql_insert .= "ip='".$this->getRemoteAddress()."', " ; $sql_insert .= "browserName='".$browserName."', " ; $sql_insert .= "browserVersion='".$browserVersion."', " ; $sql_insert .= "platformName='".$platformName."', " ; $sql_insert .= "platformVersion='".$platformVersion."', " ; $sql_insert .= "browserUserAgent='".$browserUserAgent."', " ; $sql_insert .= "referer='".$referer."', " ; $sql_insert .= "page='".$page."', " ; $sql_insert .= "time='".date_i18n('Y-m-d H:i:s')."', " ; $sql_insert .= "singleCookie='".$singleCookie."', " ; $sql_insert .= "refreshNumber='".$refreshNumber."'" ; $sql_insert .= $this->geolocate() ; $wpdb->query($sql_insert) ; |
The input would then be output on the plugin’s admin page if the plugin’s “Do you want to manage the web statistics locally?” and “Do you want to display the last viewed pages?” settings were checked. So if successful, the attack would have caused JavaScript code to run on that admin page.
Free Warning
As the vulnerability is being targeted by a hacker, we are adding accurate data on it to the free data that comes with our Plugin Vulnerabilities plugin.