6 Sep 2016

Yet Another Very Vulnerable Plugin Returned to The WordPress Plugin Directory Without Actually Being Fixed

When it comes making sure that vulnerabilities in WordPress plugins get fixed we play important role in making that happen, but we are having to play an outsized role because others are not doing their part, which has once again lead to websites remaining vulnerable to being hacked for much longer than they should have been.

One of things that we do to provide the best data on vulnerabilities in WordPress plugins to our customers is that we monitor our websites and some outside data sources for evidence that hackers are targeting plugins. In many case the evidence doesn’t itself give any indication of what the vulnerability the hacker is targeting, just that the hacker is looking for usage of the plugin by requesting a .css or .js files in the plugin’s directory. From there we try to determine if the hackers is targeting a previously known vulnerability or there is a vulnerability that exists in the current version that hacker could be targeting. Through that work we have found numerous vulnerabilities included many that it looks like hackers have known and been exploiting for months and sometimes longer. What we found fairly troubling about this is that we look to be the only security company doing, even though at least one other would certainly like you to think they are.

That brings us to our recent discovery of a persistent cross-site scripting (XSS) vulnerability in the WP-Piwik plugin. While combing through data from one of the outside data sources we monitor, we came across the possibility that a hacker had been targeting the plugin back in January. In looking over the plugin for the kind of vulnerability that hackers might exploit (many types of vulnerabilities are unlikely to be targeted by them), we noticed that anyone could change the plugin’s settings. The potential damage that could be done using that depends on what impact the plugin’s settings can have on the website. In this case, the settings could be changed to load JavaScript on the website’s page and that in turn could be used to serve malware on them. This isn’t a hypothetical issue as in February of last year, this type of vulnerability was exploited on a large scale to serve malware on websites using the Fancybox for WordPress plugin.

Once we had found the vulnerability we quickly notified the developer of the details of the issue, suggested they may want to request to have the plugin automatically updated after being fixed, and let them know that if needed any help in dealing with it, to get back to us. Two weeks went by without any response or the vulnerability being fixed. At that point we disclosed the vulnerability, added it to the data that comes with our service’s companion plugin (so that even those that don’t use the service would get alerted), and notified the Plugin Directory of the issue.

A short time later the plugin was removed from the Plugin Directory, which protected those not already using the plugin from being exposed to the issue. Those already using the plugin were left in the dark since WordPress continues to refuse to alert them in such a situation.

Two days later the plugin returned the Plugin Directory with a new version, 1.0.10, that was supposed to fixed the vulnerability, but didn’t. As those that follow our blog would already know, the WordPress’ failure to properly check over plugin’s before returning them to the directory has been an ongoing issue. In some cases you could excuse it to some extent because it would easy enough to think the vulnerability was fixed, like one situation where the code to fix the vulnerability had been added, but was one line below where it needed to be to function properly. In this case the new code was not what you would have expected to fix this, so thorough checking should have been done, but it doesn’t look like it was.

The attempted fix involved adding an additional check before saving the settings. In the function that checks if a settings change is include in the request before those changes can be applied, isConfigSubmitted(), an additional check is done by calling a new function isOptionsPage(). The function isConfigSubmitted() in 1.0.9:

617
618
619
private function isConfigSubmitted() { 
    return isset ( $_POST ) && isset ( $_POST ['wp-piwik'] ); 
}

The function isConfigSubmitted() in 1.0.10:

617
618
619
private function isConfigSubmitted() { 
    return self::isOptionsPage() && isset ( $_POST ) && isset ( $_POST ['wp-piwik'] ); 
}

The isOptionsPage() function is intended to check “if current page is WP-Piwik’s option page” by comparing two values:

1243
1244
1245
1246
1247
public static function isOptionsPage() { 
    require_once(ABSPATH . 'wp-admin/includes/screen.php'); 
    $screen = get_current_screen(); 
    return $screen == self::$optionsPageId; 
}

When we tried our proof of concept (included in our post about the vulnerability) we found that this check didn’t stop the exploitation of the vulnerability. The reason for that is that two values being compared are empty and therefore the same.

We notified the developer of the issue along with a suggestion on how to properly fix the issue, they responded shortly afterward and two days later version 1.0.11 was released, which fixed the issue.

The fixed involved using another new check in the isConfigSubmitted() function by calling the isValidOptionsPost() function:

617
618
619
public static function isConfigSubmitted() { 
    return isset ( $_POST ) && isset ( $_POST ['wp-piwik'] ) && self::isValidOptionsPost(); 
}

The function isValidOptionsPost() checks to make sure that request is coming from someone who should be able to make changes to the settings, by checking current_user_can( ‘manage_options’ ), and that they intended to make the changes, by checking check_admin_referer( ‘wp-piwik_settings’ ), to prevent against cross-site request forgery (CSRF):

1243
1244
1245
public static function isValidOptionsPost() { 
    return is_admin() && check_admin_referer( 'wp-piwik_settings' ) && current_user_can( 'manage_options' ) ; 
}

WordPress Needs to Improve

The developer could have improved the situation by responding quicker and getting back to us the first time we contacted them so we could have worked together to come up with a proper fix instead of requiring two releases to make that happen. But since developers are not likely to running into situation like this very often, trying to improve things by focusing on them seems to be difficult. Instead the people behind WordPress who deal with this type of issue on an ongoing basis seem to be the better are to focus to improving the situation. What exactly needs to be done isn’t clear because their handling of vulnerable plugins is rather opaque (making it less opaque could be starting point for fixing not only this, but other issues with the process). Maybe there needs to additional checking done before returning a plugin or maybe there needs to be a better understanding of how to checks thing over by the people already doing that. Whatever the case, we would be happy to help them, since getting these vulnerabilities fixed as quickly as possible is our goal.

Leave a Reply

Your email address will not be published.