22 Feb

SiteGround Caused 300,000+ of Their Customers Websites to be Insecure Due to Their Plugin SG Optimizer

When it comes to blame for the poor state of web security one of the parties that should get more blame than they seem to get are web hosts. Not only do they often poorly handle security themselves, but increasingly they have been partnering with really bad security companies, allowing those security companies to cause even more problems. SiteGround is one of those web hosts, with their partnership with Sucuri (which in turns is owned by another web host, GoDaddy, with a horrible security record of their own). Sucuri is a  company that among too many issues to go through, tries to scare people in to hiring them to do unneeded work, lacks a basic understanding of security, and causes their customers websites to remain insecure when they were easily fixed by people not claiming to have the level expertise that Sucuri claims to have.

Considering that SiteGround would have so low regard for their customers to partner with Sucuri, it probably isn’t all that surprising that they have also caused 300,000+ of their customers’ websites (according to wordpress.org) that use their plugin SG Optimizer, to be insecure due to really poor security handling in the plugin.

What stands out about this is how long it took them to fix this. What lead us to look into their plugin and find vulnerabilities in it was SiteGround’s claim about quickly providing protection against a vulnerability in another plugin. In that case they touted how they had provided protection the same day a vulnerability was disclosed. That vulnerability was already fixed several days before the disclosure and was unlikely to have been exploited, so the claimed provided protection wasn’t all that meaningful. When it came to unfixed vulnerabilities in their own plugin though it took them nearly three weeks to fix it, when it could have reasonably done in days at the most.

What we found when we started to look at their plugin three weeks ago was that there was a lack of protection against cross-site request forgery (CSRF) when taking actions permitted by the plugin, due to a lack of a nonce sent with the request to take those (and also a lack of check to make sure a valid nonce was sent when processing the request). That could allow an attacker to cause a logged in Administrator to take actions provided through the plugin, without intending it. The plugin allows changing the website’s caching settings, HTTPS enablement, and what is seems like the most likely to cause issues, it’s PHP version.

When we went to look closer at that we found there was a larger issue related to that, anyone logged in to WordPress would be able to change all those things as well. As an example of that, let’s look at the code that handles changing the URLs that get excluded from caching. That is handled through a function named update_blacklist(), which the plugins register to be available through WordPress’ AJAX functionality:

79
add_action( 'wp_ajax_sg-cachepress-blacklist-update', array( $this, 'update_blacklist' ) );

The way that is registered allows anyone logged in to access the function. The function, located in the file /class-sg-cachepress-admin.php, didn’t do a check to make sure the requests is from a user that should have access to it (or check for a valid nonce to prevent CSRF) before updating the excluded URLS:

260
261
262
public function update_blacklist() {
	die((int)$this->options_handler->update_option('blacklist',$_POST['blacklist']));
}

That has now been fixed adding by adding those checks:

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
public function update_blacklist() {
	if (!current_user_can( 'manage_options' )) {
		return;
	}
 
	if (!isset($_POST['nonce'])) {
		return;
	}
 
	if (!wp_verify_nonce( $_POST['nonce'], 'sg-cachepress-blacklist-update' )) {
		return;
	}
 
	die((int)$this->options_handler->update_option('blacklist',$_POST['blacklist']));
}

After that we ran the plugin through our Plugin Security Checker, which does limited automated security checks of WordPress plugins (and is now accessible through a WordPress plugin of its own),  and it identified another possible issue in one of those AJAX functions:

A quick test of that showed that in fact the plugin contained a reflected cross-site scripting (XSS) vulnerability since it outputs user input without escaping it first.

That was fixed by restricting access to the relevant function and escaping the input using strip_tags():

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
function message_hide()
{
	if (!current_user_can( 'manage_options' )) {
		die();
	}
 
	if (!isset($_POST['nonce'])) {
		die();
	}
 
	if (!wp_verify_nonce($_POST['nonce'], 'ajax-notification-nonce')) {
		die();
	}
 
	$id = $_POST['notice_id'];
	$this->options_handler->disable_option('show_notice_' . $id);
 
	echo strip_tags($id);
	wp_die();
}

It really doesn’t say good things about the security of WordPress plugins in general that you have a plugin with 300,000+ active installs that has a vulnerability that can be picked up by our tool (and its good reason to check the plugins you use over and possibly have a security review any flagged as possibly containing security issues).

The good news in all of this is that none of those security issues is the kind of thing that hackers would likely try to exploit.

Proof of Concept for Changing Excluded URLs

The following proof of concept will cause the value of the excluded URLS to be changed to “test”, when logged in to WordPress

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">
<input type="hidden" name="action" value="sg-cachepress-blacklist-update" />
<input type="hidden" name="blacklist" value='test' />
<input type="submit" value="Submit" />
</form>
</body>

Proof of Concept for Reflected Cross-Site Scripting (XSS) Vulnerability

The following proof of concept will cause an alert box with the message “XSS” to be shown, when logged in to WordPress. Major web browsers other than Firefox provide XSS filtering, so this proof of concept will not work in those web browsers.

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">
<input type="hidden" name="action" value="sg-cachepress-message-hide" />
<input type="hidden" name="notice_id" value='<script>alert(document.cookie);</script>' />
<input type="submit" value="Submit" />
</form>
</body>

Timeline

  • February 2, 2018 – Developer notified.
  • February 5, 2018 – Developer responds.
  • February 22, 2018 – Version 4.0 released, which fixes vulnerabilities.
02 Feb

SiteGround’s Poor Handling of Security Surrounding WordPress Plugins

One of the many problems we see when it comes to improving the security of websites is that it easy for companies to make it sound like they are doing impressive things in regards to security when they are doing very little or even doing things in way that put their customers at risk.

Recently we ran across an example of that involving the web host SiteGround, which was touting their quick response to a WordPress plugin vulnerability in a blog post:

Тoday, a serious vulnerability issue with one of the vastly used Yith plugins – the WooCommerce Wishlist was discovered by Sucuri. The latest plugin version – 2.2.0 patches the vulnerability but all versions prior to it are at risk. To protect our customers, who haven’t updated their plugin, our security team started working immediately and a WAF rule was just applied on our servers.

We’re very proud of our internal WAF (Web Application Firewall) system that protects all SiteGround shared and cloud servers. It allows us to dynamically add different rules across our network and block hacking attempts. The moment we got notified about the issue with YITH WooCommerce Wishlist plugin, our security team started working on the case. We’ve managed to come up with a rule, that shields you against potential attacks utilizing this vulnerability. Although this does not patch the problem in its core, we’ve added protection against those, who try to utilize it. This said, we urge you to update to the latest plugin version, which includes the official patch for this vulnerability.

As we will get to in a second this really isn’t all that impressive, but based on the comments on the post, others thought so.

That post was written on January 17, which was six days after the vulnerability was fixed. If a hacker had been interested in the vulnerability they likely could have already been exploiting shortly after it was fixed, considering that it should have not been hard to figure out what it was based on the changelog entry for it:

  • Fix: fixed security vulnerability, causing possible SQL Injections (huge thanks to John C. and Sucuri Vulnerability Research team)

That is one of a number of reasons it would be much better for people to be keeping their plugins up to date then rely on a WAF for protection. Another one that is important to consider, is that the protection like that may not work all that well, as we and others have found that type of protection can be rather limited in what it stops. We have yet to see any WAF providers that provide results from testing, much less independent testing, that their WAF is effective at protecting websites from real threats (despite that seeming like it should be a baseline requirement for anyone considering paying for such a product/service). By comparison, since vulnerability fixes are public there is at least the chance that others will have checked over things. While that doesn’t always happen, it does happen enough to regularly lead to further improvements to protection against those vulnerabilities, which likely can’t be said about those WAFs.

What is the much larger issue here though, is that this was the only vulnerability they made an announcement about providing protection for last month. That is rather underwhelming when you considering that we added data on 44 newly disclosed vulnerabilities to our data set last month, including 11 that haven’t been fixed. So why that vulnerability and not any of the other 43?

That plugin is fairly popular, but as people dealing with security of websites should really know, the popularity of a plugin has little role in the risk of a vulnerability being exploited, so that would seem like it isn’t reason (or at least shouldn’t be).

It shouldn’t be the type of vulnerability either, seeing as SQL injection vulnerabilities are not something that in most variants is something that is of much chance of being exploited on the average website.

Instead it looks like there is simple explanation, that vulnerability was the only one disclosed by their security partner Sucuri last month (a partnership that has caused SiteGround customers to be provided false claims that websites are hacked due to SiteLock’s really poor scanner). In fact going back through last year, the only other blog entry announcing protection against a WordPress plugin vulnerability was another one disclosed by Sucuri. Considering that that neither of those was one that is of much concern to the average website and considering that there have been many vulnerabilities that were already being exploited or likely to be exploited, they don’t appear to have to done much for their customers when it comes to protecting against vulnerabilities in WordPress plugins. Unlike SiteGround, we don’t passively wait to be notified about disclosed vulnerabilities, so we can help protect our customers from many more vulnerabilities (we also provide a plugin to handle automatically updating plugins).

In looking over SiteGround’s other recent blog entries we noticed more concerns when it comes to their handling of security. For example, in one post they were touting their “AI-based” supposed prevention of brute force attacks, despite that type of attack not happening. Considering at best that they are misusing basic security terminology, something their partner Sucuri has claimed is a red-flag when it comes to security (though amazingly equally applies to Sucuri itself), it probably isn’t all that surprising that their WordPress plugin, which has over 300,000+ active installs according to wordpress.org, has multiple easy to spot security vulnerabilities.

One of the vulnerabilities is so easy to spot that it was picked up by our Plugin Security Checker, which does limited automated security checks of WordPress plugins (and is now accessible through a WordPress plugin of its own). We have notified SiteGround of the details of the vulnerabilities and will be disclosing them once they have had a chance to fix them.