Before we start analyzing the vulnerabilities, let us have a look at the general statistics to understand what the results really indicate. Our scan includes all plugins that are hosted in the official Wordpress repository1 and have at least one PHP file. If there are releases, we use the latest release, otherwise we use the code from the trunk2. There are 44,705 plugins that fulfill this criteria. The average amount of files per plugin is 8.43 and the average amount of lines per plugin is 602. As concluded from the following statistics, the majority of the plugins are very small. For example, over 14,000 plugins (32%) consist of only 2-5 files.
As stated in our introduction, there are 10,523 larger plugins with more than 500 lines of code and 4,559 of them (43%) contain at least one medium severity issue, such as cross-site scripting. But how are the issues spread among the plugins? To answer this question, we calculated the number of plugins with no issues, only low severity issues, medium severity and below issues, high severity and below issues, and critical severity and below issues.
The result indicates that a vast majority of plugins do not have any vulnerabilities at all. Given a total amount of 67,486 detected security issues this means that the plugins that do have at least one security issue must have a lot of them. Our hypothesis is that this is the case because most plugins are very small. It is much harder to introduce a vulnerability in 100 lines of code than it is in 5,000 lines of code. To verify our hypothesis we calculated the relation of lines of code to number of issues.
The blue dots show that most plugins have less than 1,000 lines of code. The orange dots on the other hand show that the plugins with less than 1,000 lines of code have close to zero issues on average. When the blue dots start approaching 1, the orange dots start to spread out. This supports our theory that most plugins do not have vulnerabilities because they are small.
Issue Type Distribution
Another important statistic is the distribution of issue types in order to understand the severity of the detected issues in the plugins.
Unsurprisingly, the most common issues are cross-site scripting vulnerabilities which occur whenever user input is printed without proper sanitization to the HTML response page. For one, these issues appear frequently because the output of data is the most common operation of PHP applications3 and thus more affected by security violations than other operations. And second, given the diversity of HTML contexts and its pitfalls in sanitization these issues are easily added. Cross-site scripting vulnerabilities are quite serious in Wordpress because they can be used, for example, to inject PHP code through the template editor. Luckily, they do require interaction with an administrator though.
The second most common issues are SQL injection vulnerabilities. They are even more severe than cross-site scripting vulnerabilities because - in the worst case - they can be used to extract sensitive information from the database - for example passwords - without any user interaction at all. As a result they can be used for fully automated attacks.
All other issue types are comparatively rare and negligible in the overall picture.
Another information we were interested in is what plugins attackers are trying to exploit most actively at the moment. We are running a small Wordpress honeypot for quite some time know and could extract the information from our logs. Overall, over 200 attacks were recorded from January of 2016 to December of 2016, related to the following Wordpress plugins:
- Revolution Slider: 69 attacks
- Beauty & Clean Theme: 46 attacks
- MiwoFTP: 41 attacks
- Simple Backup: 33 attacks
- Gravity Forms: 11 attacks
- Wordpress Marketplace: 9 attacks
- CP Image Store: 8 attacks
- Wordpress Download Manager: 6 attacks
All attacks relate to publicly known vulnerabilities that are well documented4. Most of the vulnerabilities are very easy to exploit and allow the execution of arbitrary code which makes them interesting for the creation of PHP-based botnets. Additionally, we observed frequent brute-force attempts on the administration area of the Wordpress honeypot blog.
As we saw in the previous section, Wordpress plugins suffer from all kinds of typical web vulnerabilities. In this section, we will describe some of our uncovered issues in detail. We reported all detected vulnerabilities earlier this year and patches are available.
All In One WP Security & Firewall
The first plugin that will be analyzed in detail is called All In One WP Security & Firewall. It adds some additional layers of security to Wordpress, for example a brute force protection for the login or file permission checks. There are definitely quite a lot of good ideas integrated into this plugin, but some functionality cuts both ways. Meaning, it closes some attack vectors and opens new ones. Take the file permission manager for example. It is intended to change file permissions to something secure, but if an attacker gets access to the administration panel it can also be used to change the file permissions to something insecure, i.e. make read-only files writable. Another dangerous function is the ability to backup and restore the Wordpress configuration files because it can be used to inject PHP code into
wp-config.php. In combination with the file permission manager, a code execution is guaranteed in case there is a cross-site scripting vulnerability somewhere on the page. Indeed, RIPS detected one in the plugin itself. In the end, the usage of this security plugin can bring more security risks than running Wordpress without it.
This cross-site scripting vulnerability is quite interesting because at the first look this does not seem to be exploitable. After all, the function
render_tab3() is only called when the parameter
tab is tab3. We can still exploit this because the function
$_REQUEST['tab']. The super global
$_REQUEST is a combination of
$_COOKIE. So what happens if we send
tab as both a GET and a POST variable? The POST value overwrites the GET value, but only inside of
$_REQUEST. So all we have to do is to send a cross-site scripting payload as POST parameter
The cross-site scripting vulnerability is of course fixed by now, and so are other issues that we reported. Some of the issues still exist though, because the only way to fix them is by removing the functionality completely.
The second plugin that will be dissected is called Podlove Publisher, a Wordpress plugin to manage podcasts. It suffered from multiple SQL injections and cross-site scripting vulnerabilities (funnily enough also in a parameter named
tab) that are fixed by now. The SQL injections were all caused by the following code.
The author tried to save some work by dynamically setting properties of the model from user input, called mass-assignment. The idea is not bad in general, but care should be taken when every property of an object can be tainted with user input, even properties that are not supposed to be set by the user, like the
id. Usually, the ID is supposed to be an integer value that stems from
insert_id, but the mass-assignment allows an attacker to overwrite and use it to extend the SQL query and retrieve sensitive information from the database. All other properties are escaped by
On a positive note, all vulnerabilities in this plugin were fixed very fast and a secure version was available after only 2 days. This was one of the fastest responses we experienced so far, so if you are searching for a Wordpress podcast plugin, give it a try.
RIPS ❤ Wordpress
We incorporated detailed knowledge about Wordpress internals into the RIPS engine. There are multiple reasons why this is important. For example, consider the following hook.
The hook modifies the
WHERE conditions of database queries and makes them vulnerable by appending user input from the Wordpress function
get_query_var(). For a human reader this is pretty obvious - for a computer it is not. The user input never touches a sensitive function like
mysql_query() directly, so only if the analyzer knows that the return values of
posts_where hooks are used inside of a sensitive function it can detect the vulnerability.
The core of Wordpress has 2,472 locations that can be hooked5. Furthermore, Wordpress provides many functions to encode or escape6 variables, such as
esc_sql(), that are commonly used in plugins. Due to a strong dedication to PHP and intensive research, RIPS supports the security analysis of complex platforms such as Wordpress with all its functionalities and oddities. Hence, it is possible to analyze a Wordpress plugin without analysis of the Wordpress core itself. This allowed us to scan 44,705 plugins on a single machine within one day.
Wordpress is not as insecure as its reputation would suggest. Rather it is a top target due to its incredible prevalence. Yes, there are a lot of vulnerabilities in the Wordpress ecosystem, but most of them are in a small percentage of the plugins. While many plugins do not contain vulnerabilities at all because of their small size, the ones that do have issues, have a lot of them. The more lines of code a plugin has, the more vulnerabilities it has on average. Please note that we do not claim to have found all vulnerabilities that possibly exist in all plugins nor that we can guarantee the exploitability of the detected issues. As a take-away of this post, we recommend to install only plugins that you really need, to keep all plugins up to date, and to choose strong passwords.
Follow us on Twitter to be notified when the next gift of our advent calendar is opened!
APAV Time Table
Disclaimer: The information provided here is for educational purposes only. It is your responsibility to obey all applicable local, state and federal laws. RIPS Technologies GmbH assumes no liability and is not responsible for any misuse or damages caused by direct or indirect use of the information provided.
- http://plugins.svn.wordpress.org/ [return]
- https://en.wikipedia.org/wiki/Trunk_%28software%29 [return]
- http://homepages.cwi.nl/~jurgenv/papers/ISSTA-2013.pdf [return]
- https://blog.sucuri.net/2014/09/slider-revolution-plugin-critical-vulnerability-being-exploited.html [return]
- https://developer.wordpress.org/?s=&post_type%5B%5D=wp-parser-hook [return]
- http://blog.dewhurstsecurity.com/2016/08/18/wordpress-plugin-security-cheat-sheet.html [return]