WordPress Plugin Developer Security Advisory: StellarWP
One of the little understood realities of security issues with WordPress plugins is that the insecurity of them is not evenly spread across those plugins. Instead, many developers are properly securing their plugins and others get them properly secured when alerted they haven’t done that. A smaller number of plugin developers either are unable or unwilling to properly secure their plugins. With the latter group, among the issues we have seen, are developers who have introduced new serious vulnerabilities that are substantially similar to vulnerabilities that they know have been exploited in their plugins.
In situations where we become aware of developers who have shown that inability or unwillingness to properly secure their plugin, we are releasing advisories to warn customers of our service and the wider WordPress community of the risk of utilizing those developers’ plugins. In addition to checking those posts on our website for information on those advisory, we provide access to the information in several other forms. That includes through the companion plugin for our service, even when not using the service, as well as through a web browser extension and through separate data accessible from our website.
The latest addition to our advisories involves a developer who has a terrible track record with security despite being the developer of one of the most popular security plugins for WordPress. The popularity of the security plugin has declined pretty significantly despite claiming that the plugin “[r]educe[s] your WordPress website’s risk to nearly zero.” That might have something to do with the fact that the plugin doesn’t actually offer the claimed security. That suggests either the developer isn’t honest or lacks a basic understanding of security. One of those probably explains the poor security across their plugins.
The developer is StellarWP, which is a combination of several previously independent plugin developers. StellarWP is in turn part of Liquid Web, which is owned by a private equity company. That could allow the company to spend the money to get security right or it could lead to cutting corners. It has been the latter of those for years.
Kadence Blocks Vulnerability Keeps Not Getting Fixed
In August 2023, we posted about StellarWP having failed to detect a serious vulnerability in the Kadence Blocks plugins for five months and mentioned past bad security handling coming from the company:
The developer of that plugin, StellarWP, has had a terrible security track record despite developing one of the most popular security plugins. Including failing to fix a vulnerability that their security plugin was warning about and failing to implement basic security in another plugin, leading to a zero-day. That makes the issue with Kadence Blocks not all that surprising.
In May of last year, we warned our customers that they had failed in an attempt to fix a different vulnerability in the plugin. We tried to work with them to address that, but we found that they were directing reporting vulnerabilities away from themselves to a company trying to profit off of vulnerabilities. That was despite them having a page about responsible disclosure that says “it is a standard practice in security research to responsibly and privately disclose discovered vulnerabilities to the software vendor prior to public release. This is even more critical when we work together to protect users in an open source space such as the WordPress community.” We offered to help them fix the vulnerability once they stopped doing that. They didn’t take us up on that. Instead they appear to have made over ten additional attempts to fix the vulnerability without accomplishing that.
Continued Usage of Insecure maybe_unserialize() Function
Last year another security provider, Wordfence, got press coverage for themselves in a situation where they ignored that a vulnerability in a plugin from StellarWP was caused in part by a long known security issue in WordPress. That security issue is with the WordPress function maybe_unserialize(). WordPress’ response so far has not been to address that, but to suggest that plugins shouldn’t use it. StellarWP (and Wordfence) could have used their voice in the WordPress community to push for fixing that or they could have stopped using it in their plugins to avoid something known to be insecure. That hasn’t happened. That is, while having more instances of the type of vulnerability allowed by that insecurity being found and getting press coverage.
The original situation highlighted another common issue, developers not providing a clear method for contacting them about security issues. Wordfence reported not even having gotten a response from StellarWP weeks after notifying them of the vulnerability with what seemed to be the wrong contact method. There is a standard that they could support and promote other developers to help to address that, but they haven’t.
Violating Security Related WordPress Plugin Guideline With Their Security Plugin
The 13th guideline for the WordPress Plugin Directory requires that plugins use the version of third-party libraries included with WordPress instead of including their own “[f]or security and stability reasons.” We are in the process of adding detection of those libraries and warning about plugins that include those libraries to our Plugin Security Scorecard. That led to us noticing that StellarWP’s security plugin, Solid Security, is using a rather out of date version of the jQuery Form library, which is already included in WordPress. In the file /core/modules/core/js/mc-validate.js, they have version 3.51.0 of that. That was superseded in Februrary 2017. The version included in WordPress is up to date.
Recent Plugin Missing Basic Security
One attempted defense of StellarWP’s poor handling of security might be that they have inherited plugins that were insecure before they became part of the unit. While that isn’t a good defense in our view, it wasn’t hard to find that a recent plugin is insecure. And notably, it is insecure because of code that is branded as being from StellarWP itself. That plugin being Solid Performance, which was released in August.
In the file /vendor/vendor-prefixed/stellarwp/telemetry/src/Telemetry/Opt_In/Opt_In_Subscriber.php, the plugin registers a function to run during admin_init, which makes it accessible to even those not logged in to WordPress:
40 | add_action( 'admin_init', [ $this, 'set_optin_status' ] ); |
The code is for opting in a website to telemetry, which should only be able to be done by an Administrator, but the code lacks a capability check to limit access:
51 52 53 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 | public function set_optin_status() { // We're not attempting an action. if ( empty( $_POST['_wpnonce'] ) ) { return; } $nonce = sanitize_text_field( $_POST['_wpnonce'] ); if ( ! wp_verify_nonce( $nonce, 'stellarwp-telemetry' ) ) { return; } // We're not attempting a telemetry action. if ( isset( $_POST['action'] ) && 'stellarwp-telemetry' !== $_POST['action'] ) { return; } // The user did not respond to the opt-in modal. if ( ! isset( $_POST['optin-agreed'] ) ) { return; } $stellar_slug = Config::get_stellar_slug(); if ( isset( $_POST['stellar_slug'] ) ) { $stellar_slug = sanitize_text_field( $_POST['stellar_slug'] ); } $opt_in_text = ''; if ( isset( $_POST['opt_in_text'] ) ) { $opt_in_text = sanitize_text_field( $_POST['opt_in_text'] ); } // User agreed to opt-in to Telemetry. if ( 'true' === $_POST['optin-agreed'] ) { $this->opt_in( $stellar_slug, $opt_in_text ); } |
The code does include a nonce check, but that isn’t supposed to be used for doing a capability check as the WordPress documentation notes:
Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can(), and always assume nonces can be compromised.
That should have been caught during a security review of the plugin before it was released. Yet 8 months later it still hasn’t been addressed.
That isn’t a one-off accident, as the same issue exists in another area that should have been caught by a security review, AJAX accessible functions. In the file /vendor/vendor-prefixed/stellarwp/telemetry/src/Telemetry/Exit_Interview/Exit_Interview_Subscriber.php, the function ajax_exit_interview() is registered to be accessible to anyone logged in to WordPress:
43 | add_action( 'wp_ajax_' . self::AJAX_ACTION, [ $this, 'ajax_exit_interview' ] ); |
It is meant to be accessed when uninstalling the plugin, so again, only Administrators should have access, but there is no capability check:
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | public function ajax_exit_interview() { $uninstall_reason_id = filter_input( INPUT_POST, 'uninstall_reason_id', FILTER_SANITIZE_SPECIAL_CHARS ); $uninstall_reason_id = ! empty( $uninstall_reason_id ) ? $uninstall_reason_id : false; if ( ! $uninstall_reason_id ) { wp_send_json_error( 'No reason id provided' ); } $uninstall_reason = filter_input( INPUT_POST, 'uninstall_reason', FILTER_SANITIZE_SPECIAL_CHARS ); $uninstall_reason = ! empty( $uninstall_reason ) ? $uninstall_reason : false; if ( ! $uninstall_reason ) { wp_send_json_error( 'No reason provided' ); } $plugin_slug = filter_input( INPUT_POST, 'plugin_slug', FILTER_SANITIZE_SPECIAL_CHARS ); $comment = filter_input( INPUT_POST, 'comment', FILTER_SANITIZE_SPECIAL_CHARS ); $comment = ! empty( $comment ) ? $comment : ''; $nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_SPECIAL_CHARS ); $nonce = ! empty( $nonce ) ? $nonce : ''; if ( ! wp_verify_nonce( $nonce, self::AJAX_ACTION ) ) { wp_send_json_error( 'Invalid nonce' ); } $telemetry = $this->container->get( Telemetry::class ); $telemetry->send_uninstall( $plugin_slug, $uninstall_reason_id, $uninstall_reason, $comment ); |
Avoid StellarWP’s Plugins
Those examples provide clear evidence of a fundamental continuing problem with StellarWP’s handling of security. They have shown no willingness to address the problem and in our own experience been hostile to attempts to help even fully fix issues. That they are a major security provider, which makes the whole thing even worse.
We would recommend avoiding their plugins, unless they can show that they have made significant changes to their handling of security.