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.
21 Feb

When The Solution to a Vulnerability in a WordPress Plugin is to Have Updated It Years Ago

Earlier today we were discussing an example of the problem with WordPress plugins not being kept up to date. Recently we have also been looking in to another example of that, which also shows the type of work we do to make sure our clients have the best data on vulnerabilities in WordPress plugins and also some of what developers have to deal with when it comes to claims of them in their plugins.

One of things we do to keep track of vulnerabilities in WordPress plugins is to monitor the Support Forum on wordpress.org for topics related to those. Recently we came across a thread for the plugin Spider FAQ that indicated there might be a vulnerability in it:

Today OpenBugBounty wrote us a mail, that we have a css vulnerability problem with the searchfield from Spider-Faq.

One resolution is, to filter some Signs in the Searchfield. Can anyone tell me, where the Searchfield is located and where we should enter the Filter for the Symbols?

That sounded like it was describing a reflected cross-site scripting (XSS) vulnerability in the plugin’s search functionality on the frontend of the website. When we went to check on that though we found that things seemed relatively secure. What seemed to be the relevant code escapes what is submitted to be searched for (in the form of POST input search) to prevent XSS:

<div align="right"><input type="text" class="search_keyword" id="<?php echo 'skey'.$faq->id ?>" name="search<?php echo $faq->id ?>" value="<?php if(isset($_POST['search'.$faq->id])) { echo $_POST['search'.$faq->id]; } ?>" />

It looks like it would be better to be using esc_attr() instead of esc_html(), but other than things seemed fine.

At that point we were not sure what was going on and we waited to see if any more information would be disclosed in the thread that might make things clearer (due to the terrible moderation of the Support Forum, we avoid participating in it at this time).

After a response from the developer, the original poster responded with additional information. What was helpful to us in that was that they listed the address where this was occurring. With that we tried to see what version of the plugin was being used on the website, since it could have been that a vulnerability had existed in older versions of the plugin.

We were quickly able to identify that the version of the plugin being used on the website was from the 1.0.x series. That series was indeed vulnerable to this issue, as there is no escaping when the search term is output:

<div align="right"><input type="text" class="search_keyword" id="<?php echo 'skey'.$faq->id ?>" name="search<?php echo $faq->id ?>" value="<?php if(isset($_POST['search'.$faq->id])) { echo $_POST['search'.$faq->id]; } ?>" />

Version 1.1, which fixed that, was released on November 19 of 2013. So the plugin hasn’t been updated in over four years on that website.

Proof of Concept

Submitting the following proof of concept as the search term on a frontend page for the plugin will cause an alert box with the number 1 to be shown. Major web browsers other than Firefox provide XSS filtering, so this proof of concept will not work in those web browsers.

“><script>alert(1);</script>

12 Feb

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in WP Pipes

From time to time a vulnerability is fixed in a plugin without the discoverer putting out a report on the vulnerability and we will put out a post detailing the vulnerability so that we can provide our customers with more complete information on the vulnerability.

When we started developing our Plugin Security Checker (which is now accessible through a WordPress plugin of its own) it only ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for half off (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

12 Feb

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in cformsII

From time to time a vulnerability is fixed in a plugin without the discoverer putting out a report on the vulnerability and we will put out a post detailing the vulnerability so that we can provide our customers with more complete information on the vulnerability.

Recently we were looking into another possible security issue that had been claimed to have been fixed in the plugins To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for half off (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

06 Feb

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in WP Retina 2x

From time to time a vulnerability is fixed in a plugin without the discoverer putting out a report on the vulnerability and we will put out a post detailing the vulnerability so that we can provide our customers with more complete information on the vulnerability.

An advisory released by the JPCERT/CC and IPA states that a reflected cross-site scripting (XSS) vulnerability had been fixed in version ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for half off (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

17 Jan

It Looks Like Our Plugin Security Checker Caught a Vulnerability That Was Missed by a WordPress Plugin Directory Review

In continuing to work on improving 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 been interested to see where it can already provide value over what is already being done to improve the security of plugins. We recently got what looks to be an example of it catching something that was missed by the team managing the Plugin Directory.

Last Tuesday we were contacted by one of our customers, J.D. Grimes, to let us know that he had noticed that an attempt to fix a vulnerability in the plugin Media from FTP looked like it had failed to fully fix the vulnerability, but he didn’t have time to verify that or contact the developer about that. We took a look, confirmed that the fix was incomplete, and then worked with the developer to implement a better fix. A new version with that second fix was released later the same day.

At some point on Thursday the plugin was closed on the Plugin Directory. No explanation was given why that was, but based on the subsequent changes made and past experience, we would guess that the plugin was belatedly closed due the then fixed vulnerability and then the Plugin Directory required additional changes be made based on a privacy and security review done after it was removed. According to their documentation that should involve the following:

  • Don’t phone home without informed user consent
  • Collection of user data must be “opt-in” only and have the relevant option set to disabled by default
  • Validate and sanitize untrusted data before processing (See: Data Validation)
  • Escape all data before output (See: Data Validation)
  • Do not use URL shorteners
  • Use prepare() and $wpdb for SQL calls

Sometime on Thursday prior to the plugin having been closed someone ran the plugin through our Plugin Security Checker and it detected a possible issue. We have been doing spot checks on what is being flagged by that to improve the quality of the results (last week we fixed one false positive and another issue that could have lead to false positives through that), so we went to check on that. Looking at the details of the issue identified, which are available through the tool’s new Developer Mode, it certainly looked like there could be a reflected cross-site scripting (XSS) vulnerability as user input was being output without being escaped:

A quick check confirmed that this was an exploitable vulnerability (though far from a serious issue for the average website), as can be seen with the proof of concept below.

That should have been something caught by a check meant to insure that “Escape all data before output (See: Data Validation)”. Many of the changes made to the plugin after it was removed from the directory dealt with sanitizing user input, so this seems like something that should have also been caught, but the plugin returned to the directory without it being fixed.

Yesterday we contacted the developer and they released a new version, 9.90, which fixes the vulnerability by replacing the variable used (since previously a different value than intended one could be shown) and the value is escaped using esc_attr():

917
<input name="page" type="hidden" value="<?php echo esc_attr($_GET['page']); ?>" />

This seems to show using our tool could improve the security reviews that are supposed to be being done by the Plugin Directory to catch this type of issue as well as more serious issues. As we have said in the past, we would be happy to provide free access to the Plugin Directory team to the portions of the tool that normally are restricted to those using our service.

This also seems like further confirmation that that when the tool detects a possible reflected cross-site scripting (XSS) vulnerability that it is a good indication that a plugin could use a more thorough review, considering the other recently fixed issues in this plugin.

Proof of Concept

The following proof of concept will cause an alert box with the message “XSS” to be shown. 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.php?page=mediafromftp-search-register" method="POST">
<input type="hidden" name="page" value='"><script>alert(document.cookie);</script>' />
<input type="submit" value="Submit" />
</form>
</body>

Timeline

  • January 16, 2018 – Developer notified.
  • January 16, 2018 – Version 9.90 released, which fixes the issue.
04 Dec

New WordPress Plugins Continue to Use Third-Party Library with Vulnerability Disclosed Years Ago

As we continue to work on expanding what security issues our WordPress plugin security checker tool can check for, one of the things that doing that work has lead us to take notice of is the extent that plugins are using third-party libraries that haven’t been supported in a long time. Just like a plugin that hasn’t been supported, if there has been a security vulnerability that has been discovered, it is unlikely to be fixed. That is the case with the third-party library CSSTidy, which was last updated in 2007.

One of the files in that contains a reflected cross-site scripting (XSS) vulnerability that has been publicly disclosed for years, for example, it was disclosed in one WordPress plugin back in July of 2012. Where we ran across recently across it was in a disclosure by Ricardo Sanchez of it in the plugin AMP Toolbox. That plugin has included the file and therefore been vulnerable since the first release of the plugin, which was only in May of last year.

As we were looking around at this before adding a check for usage of the vulnerable file from the library to our tool we found that it was also used in the plugin Super Simple Custom CSS, which has only been around since July of last year.

In Super Simple Custom CSS the relevant files is located at /super-simple-custom-css/css_optimiser.php and the relevant lines for the issue mentioned in the previous discomposure 142 and 143 of that:

name="url" id="url" <?php if(isset($_REQUEST['url']) &&
!empty($_REQUEST['url'])) echo 'value="'.$_REQUEST['url'].'"'; ?>

The PHP code there checks if a GET or POST input “url” exists and isn’t empty, if both of those are true then the value of the input is output without being escaped.

We notified the developer of the issue a week ago. We haven’t heard back from them and no new version has been released to fix the issue. In line with our disclosure policy, which is based on the need to provide our customers with information on vulnerabilities on a timely basis, we are now disclosing this vulnerability.

Also, worth noting with this, is that this is something that the security review that is done of new plugins in the Plugin Directory is supposed to be catching, as one of the items on their security checklist is:

Escape all data before output (See: Data Validation)

Considering that the review team seems to be missing more obvious instances of this type of issue, missing this in this plugin and AMP Toolbox through a third-party library isn’t all that surprising. While we think the reviews would be better if they focused on issues more likely to lead to exploitable vulnerabilities, running newly submitted plugins through our tool would now catch usage of this library. Currently we allow paying customers to use the tool to test plugins that are not currently in the Plugin Directory, but we would be happy to provide free access to that capability to the plugin review team.

Proof of Concept

The following proof of concept will cause an alert box with the message “XSS” to be shown. 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.

http://[path to WordPress]/wp-content/plugins/super-simple-custom-css/css_optimiser.php?url=%22%3E%3Cscript%3Ealert('XSS');%3C/script%3E

Timeline

  • November 27, 2017 – Developer notified.
01 Dec

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in User Role Editor

From time to time a vulnerability is fixed in a plugin without the discoverer putting out a report on the vulnerability and we will put out a post detailing the vulnerability so that we can provide our customers with more complete information on the vulnerability.

All three changelog entries for version 4.38 of the plugin User Role Editor are security related, possibly indicating that some sort of ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for half off (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

01 Dec

Vulnerability Details: Reflected Cross-Site Scripting (XSS) Vulnerability in Special Text Boxes

Recently the web scanner service Detectify has been vaguely disclosing minor vulnerabilities in a number of WordPress plugins. It seems like they are aware that they could notify the developers of these, but usually haven’t been doing it. One of the more recent batch was an “Authenticated XSS” vulnerability in the plugin Special Text Boxes.

Based on the previous instances we figured that would refer to ...


To read the rest of this post you need to have an active account with our service.

For existing customers, please log in to your account to view the rest of the post.

If you are not currently a customer, when you sign up now you can try the service for half off (there are a lot of other reason that you will want to sign up beyond access to posts like this one).

If you are a WordPress plugin security researcher please contact us to get free access to all of our Vulnerability Details posts.

27 Nov

A WordPress Plugin Having Ten Thousand Installs Doesn’t Mean it Will Have Been Reviewed for Security

When it comes to the security of WordPress plugins there are a lot of misconceptions out there (many times they are being repeated by security companies). One of them is that a more popular plugin is going to be more secure because it has been reviewed for security. Here is an example of this claim from a recent thread on Reddit:

it is important to note that there are many thousands of WordPress plugins available, and many of them have only been installed on a handful of websites. Lesser known or less popular plugins will often not have been reviewed for security, and may contain flaws.

For that reason, I recommend avoiding plugins or themes that don’t have several thousand installs (10k+ is a good rule of thumb) on security-conscious installs, unless you can have a developer inspect and vet the code for you.

As is true of so much security advice, there isn’t any evidence presented to back that claim up, which should be a red flag. In our compiling data on WordPress vulnerabilities for our service we haven’t seen evidence that there are many security reviews being done of WordPress plugins, so assuming that more popular plugins have had a security review is not a good idea.

Another way to look at is to see if there are easy to spot vulnerabilities in say a plugin 10,000+ active installations, which happen to have an example of from some checking we were doing related to our tool for doing limited automated security checks of WordPress plugins. One of the checks included in the tool is when user input is being directly output, which could lead to reflected cross-site scripting (XSS). That is something it would have detected in the plugin WP Customer Area up until we notified the developer of the issue and it was fixed.

Before we get the details its worth mentioning that this plugin has a couple of other attributes that get cited as being ones that should be used to decide if a plugin is secure, those being that it was recently updated (as of when we went to notify the developer) and with having positive reviews:

In three files the plugin contained the following line:

 

<input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>"/>

That would echo the GET or POST input “page” without escaping it, so for example malicious JavaScript code could be output. Major web browsers other than Firefox provide XSS filtering, so to be exploitable the hacker would have to figure out a way around that or hope that the person to be exploited is using Firefox.

Now there is little bit more to this vulnerability, which gets to why simply using an automated tool, like ours, isn’t enough to determine if there are vulnerabilities. In this case to get that code to run the value of the GET input “page” has to be set to a specific value, in the case of one of the files, /src/php/core-addons/admin-area/templates/private-post-list-page.template.php, it would have to be set to “wpca-list,content,cuar_private_fil”. So that couldn’t also be used for malicious code, but you can set the POST input to another value and it looks like normally the $_REQUEST variable would contain the value of the POST input instead of the GET input.

After we notified the developer of the issue, they released version 7.4.3, which fixes the vulnerability escaping the user input:

<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']) ?>"/>

There Isn’t an Shortcut to Determining if a Plugin is Secure

With all the claims we have seen so far relate to determining if a plugin is secure, none of them have pointed to a way that you can truly determine if a plugin is secure without actually having a security review done. For example, even using a much more popular than one with 10,000+ active installations, isn’t going to mean that it is secure, as can be seen with another plugin with 300,000+ active installations we looked at recently that had five different vulnerabilities (and still has them, as they still haven’t been fixed).

Our aforementioned tool is able to detect some possible issues and we are continuing to expand what it can do, but it won’t catch a lot of issues, including any of those in 300,000+ active installation plugin at the moment.

If you want to get plugins you use checked over, that is something we offer. If you are paying customer of our service one of the things you get is the ability to suggest/vote for plugins from the Plugin Directory to receive a review from us and you can also order a security review separately from us.

Proof of Concept

The following proof of concept will cause any available cookies to be shown in alert box, when logged in as an Administrator. 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.php?page=wpca-list%2Ccontent%2Ccuar_private_file" method="POST">
<input type="hidden" name="page" value='"><script>alert(document.cookie);</script>' />
<input type="submit" value="Submit" />
</form>
</body>

Timeline

  • November 21, 2017 –  Developer notified.
  • November 21, 2017 –  Developer responds.
  • November 24, 2017 –  Version 7.4.3 released, which fixes vulnerability.