Poor Handling of Security in WordPress Plugin Directory Also Impacts ClassicPress Directory
On Friday we noted that we had started doing proactive monitoring of the plugin’s in the WordPress fork ClassicPress’ plugin directory for serious security issues and had also had run the ClassicPress plugins available in that through our Plugin Security Checker, which flags the possibility of additional less serious issues. We found a couple of plugins with minor security issues through that, including one with a vulnerability. That vulnerability was promptly fixed. Also, on Friday we ran the six plugins from the WordPress Plugin Directory also included in ClassicPress’ directory through the same tool. We found two of them had a really easy to spot minor vulnerability.
This is the kind of thing that the WordPress Plugin Directory Team could easily have systems in place to catch and automatically warn developers of. We have repeatedly offered to help them implement this type of thing, but, like other attempts help them to improve their poor handling of security, they have shown no interest.
One of the plugins we found an issue with, Stripe Payment Gateway for WooCommerce ( Basic ), has 10,000+ active installations according to wordpress.org. Despite that many installs, no one appears to have noticed the issue until now. The vulnerability has existed since the first version of the plugin was released, which happened nearly 5 years ago.
The developer did promptly respond to this, as they replied to us on Friday and a new version fixing the issue was released late last night (our time zone).
Reflected Cross-Site Scripting (XSS)
While we continue to expand on the capabilities of our Plugin Security Checker, the vulnerability in this plugin is something isn’t hard to detect. As the code would directly output user input in the form of the GET or POST input “page”, as shown from results of the tool:
Unless the value had been sanitized elsewhere (and it was not), that wouldn’t be secure and could be a vulnerability depending on how the code can be accessed.
To access the code in the latest version of the plugin (at least) the GET version of that would have set to a specified value, the POST input could be set to something else though. It looks like usually servers are configured to return the POST value before the GET value if they both exist, so by placing JavaScript code in the POST value you would have a reflected cross-site scripting (XSS) vulnerability there, as confirmed with the proof of concept below.
The developer fixed the code by escaping the value using esc_attr():
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" /> |
Proof of Concept
The following proof of concept will cause any available cookies to be shown in an alert box, when logged in as an Administrator. In Safari and other web browsers that provide XSS filtering this proof of concept will not work.
Replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin.php?page=eh-stripe-overview" method="POST"> <input type="hidden" name="page" value='"><script>alert(document.cookie);</script>' /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- June 4, 2021 – Developer notified.
- June 4, 2021 – Developer responds.
- June 6, 2021- Version 3.6.0 released, which fixes the vulnerability.