XWP Sponsors Major Cause of Avoidable Insecurity of WordPress Plugins While Leaving Vulnerabilities in Their Own Plugin
It would be easy to make significant improvements to the security of WordPress plugins available through the WordPress Plugin Directory, but year after year that hasn’t happened. A lot of the blame for that can be placed on major players in the WordPress space that are funding the current team running the plugin directory, who have blocked improvements from happening.
Two of the four members of the plugin directory team work directly for the head of WordPress, Matt Mullenweg. He also has a for-profit company, Automattic, which creates many conflicts of interest. One serious conflict of interest is that his company sells access to data on vulnerabilities in plugins through WPScan, while the plugin directory team has refused to provide that information. What makes the conflicts of interest stand out more is that the team obfuscates the connection between their members and Auttomatic.
The security reviewer on the plugin directory team works for, and is sponsored in that role, by Awesome Motive. In that role, that person is doing a very bad job. We tried to raise that with Awesome Motive late last year, but we got no response. What might explain their lack of concern with sponsoring someone who is causing so many unnecessary problems is that Awesome Motive doesn’t seem to care about the security of their plugins. Recently, they left a publicly known vulnerability in a 3+ million install plugin for two months.
The final member of the team, Mika Epstein, is the Team Representative and Senior Administrator. In that role, they were sponsored for years by Dreamhost and more recently by XWP. They have been sponsored by those companies despite appearing to be, among other issues, a serial fabulist. Like Awesome Motive, we contacted XWP last year about their sponsorship of that person. Here is the message we sent them:
We were hoping to get an understanding of if and how XWP vets Five for the Future sponsorships, for future coverage of the problem those sponsorships are having on security.
We are asking that in the context of what appears to be a rather problematic sponsorship by XWP. One of your sponsored employees, Mika Epstein, is listed as the Team Representative and Senior Administrator of the Plugin Review Team. They are also prominently mentioned on the Five for the Future page on the WordPress website, https://wordpress.org/five-for-the-future/, with a claim that they had reviewed 46,800 plugins for inclusion in the WordPress Plugin Directory (as of 2019) as part of that program through their previous employer. It seems hard to believe that one person could possibly manually review that many plugins, including reviewing the security, which is what is claimed to be done, https://developer.wordpress.org/plugins/wordpress-org/plugin-developer-faq/#what-happens-after-submission. It also appears they are not actually doing many of those reviews, as for years we have found that the manual security reviews are missing things not only should they have caught, but things that would have been caught by automated tooling that has been available to that team, but they haven’t taken advantage of. We have found other issues while reviewing possible vulnerabilities in those brand new plugins, which are claimed to be checked for during the reviews, yet were missed despite the ease of checking for them. If they were really doing the reviews, it would be odd to not take advantage of tooling that could prevent repeated problems, but if the reviews were not really happening, then it would make sense. Here are five examples from just the last three weeks of serious security vulnerabilities that got through the reviews:
- https://www.pluginvulnerabilities.com/2022/11/16/arbitrary-file-upload-vulnerability-in-html-wp/
- https://www.pluginvulnerabilities.com/2022/11/30/authenticated-option-update-vulnerability-in-lws-optimize/
- https://www.pluginvulnerabilities.com/2022/12/06/authenticated-php-object-injection-vulnerability-in-aarambha-kits-for-elementor/
- https://www.pluginvulnerabilities.com/2022/12/07/authenticated-option-update-vulnerability-in-users-control/
- https://www.pluginvulnerabilities.com/2022/12/08/remote-code-execution-rce-vulnerability-in-cx-easy-contact-form/
Beyond that issue, the team is failing the WordPress community when it comes to security repeatedly. One other problem we keep seeing is that insecure plugins return to the Plugin Directory without the vulnerability being fixed. Here is one recent example of that: https://www.pluginvulnerabilities.com/2022/11/29/wordpress-plugin-returns-to-plugin-directory-without-vulnerability-being-resolved/
Does XWP vet that sponsorships are beneficial to WordPress? Do you vet that claims made by employees about their sponsored work is accurate? Do you have a method for someone to report to you if a sponsored employee is engaged behavior that isn’t beneficial to WordPress? Any other information on your process you could provide would be helpful.
We got no response to that and the problems mentioned in that have continued.
It turns out that like Awesome Motive, XWP isn’t handling the security of their own plugins well.
Unfixed Vulnerability in XWP Plugin
In 2021, XWP wrote a rather inaccurate post about how to check if a WordPress plugin is insecure (it hits on a lot of things we have warned about when it comes to checking on the security of a plugin). In that post they wrote this:
It’s not just how the plugin is being maintained that’s important, but by whom. A lot of major players in the WordPress scene produce and maintain plugins, like Automattic and XWP. If you download a plugin that a team with a good reputation helped create, you can rest assured that you’re getting a quality product that will work with your site––or at least that you’re working with a team who will value your feedback and try their best to keep it running smoothly. If the team that works on your plugin has a reputation for falling behind on maintenance or creating low-quality code, find another plugin.
One of XWP’s plugins is Stream. That plugin has 80,000+ installs. Two days ago, a support topic was created for the plugin asking if they were going to fix a publicly disclosed vulnerability in the plugin.
Is it something you are planning to fix? https://patchstack.com/database/vulnerability/stream/wordpress-stream-plugin-3-9-2-cross-site-request-forgery-csrf-vulnerability?_a_id=431
Following that link, it is claimed that there was no reply from XWP when they were notified of the vulnerability. What is missing from the link is basic information needed to confirm there really is an unfixed vulnerability, as the only information is a vague description of cross-site request forgery (CSRF).
Looking at the plugin’s code, we found multiple instances of CSRF vulnerabilities in the latest version of the plugin. We will detail one of those in a bit.
Despite the public claim of a vulnerability, a support forum topic that was almost certainly reviewed by the moderators of the forum who micromanage any discussion of security issues, and the plugin having easy to spot vulnerabilities of the type claimed, the plugin is still available in the plugin directory.
That is a common problem and something that Mika Epstein has not only refused to address, but they have made that situation worse through their unprofessional behavior towards people trying to help fix issues like that.
The example of a CSRF vulnerability we are about to get to has been in the plugin since August 2015. A simple security review would have caught, so XWP must not have done that or had someone else to do that with the plugin in over 7 years. It would only cost them a few hundred dollars to have hired someone to have done a review.
Cross-Site Request Forgery (CSRF) Vulnerability in Stream
As an example of a cross-site request forgery (CSRF) vulnerability in the plugin, the plugin registers a function named uninstall() to be AJAX accessible to anyone logged in to WordPress:
77 | add_action( 'wp_ajax_wp_stream_uninstall', array( $uninstall, 'uninstall' ) ); |
That function, which is located in the file /classes/class-uninstall.php, will deactivate the plugin and delete its data. While code in the function limits access to doing that to a user with the Administrator role, it doesn’t include a nonce check to prevent CSRF:
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | public function uninstall() { $this->options = array( $this->plugin->install->option_key, $this->plugin->settings->option_key, $this->plugin->settings->network_options_key, ); // Verify current user's permissions before proceeding. if ( ! current_user_can( $this->plugin->admin->settings_cap ) ) { wp_die( esc_html__( "You don't have sufficient privileges to do this action.", 'stream' ) ); } if ( defined( 'DISALLOW_FILE_MODS' ) && true === DISALLOW_FILE_MODS ) { wp_die( esc_html__( "You don't have sufficient file permissions to do this action.", 'stream' ) ); } // Prevent this action from firing. remove_action( 'deactivate_plugin', array( 'Connector_Installer', 'callback' ), null ); // Just in case. if ( ! function_exists( 'is_plugin_active_for_network' ) ) { require_once ABSPATH . '/wp-admin/includes/plugin.php'; } /** * Drop everything on single site installs or when network activated * Otherwise only delete data relative to the current blog. */ if ( ! is_multisite() || $this->plugin->is_network_activated() ) { $this->delete_all_records(); $this->delete_all_options(); $this->delete_all_user_meta(); } else { $blog_id = get_current_blog_id(); $this->delete_blog_records( $blog_id ); $this->delete_blog_options( $blog_id ); $this->delete_blog_user_meta( $blog_id ); } $this->delete_all_cron_events(); $this->deactivate(); |
So an attacker could cause a logged in Administrator delete the plugin’s data and deactivate the plugin. Other code in the plugin also lacks CSRF protection, so other actions could be similarly occur without it being intended.