28 Feb 2025

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.

Leave a Reply

Your email address will not be published. Required fields are marked *