13 Nov 2024

WP Engine Failed to Vet Security of Plugin Acquired This Year or Fix Vulnerability in It Once It Was Reported to Them

When it comes to whether Matt Mullenweg or WP Engine are the bad guys in the recent, the reality is that they both have played a decidedly harmful role in the security of WordPress plugins. Sometimes that comes from them working together. Last year, we noted that WP Engine was falsely claiming that a popular WordPress plugin contained a security vulnerabilities. That was caused by them using a known unreliable source of vulnerabilities, WPScan. Incredibly, WP Engine’s VP of security admitted earlier in the year they haven’t done due diligence with WPScan’s data:

We know that there are other options out there, but given the sense of completeness and alerts for ALL relevant plugins, we never had a need to go crosscheck WPScan against anyone else.

WPScan is owned by Automattic, which is the company that Matt Mullenweg is the CEO of.

Earlier this year we noted that WP Engine had failed to actually fix a vulnerability in one of their plugins, Genesis Blocks. WPScan, in line with not being a reliable source, told people that the vulnerability had been fixed.

WP Engine’s lack of concern for security has continued since then. In July, they acquired the maker of the 100,000+ install plugin NitroPack. They clearly still haven’t done even basic security vetting of the plugin, as we found last month. The issue we identified hasn’t been fixed despite WP Engine having had over a month to address it, as we notified them of the issue on October 11. We gave them to 30 days to address it before we would disclose it. The developers have added new features and made other changes to the plugin in that time, so they have had developer resources available that could have fixed it. Here are the changelog entries for the changes made since we notified the developer about the issue:

1.17.3
* Improvement: Remove WooCommerce features for PSB users
* Improvement: WCML compatibility – use cookies
* Bug fix: Overall stability and fixes

1.17.2
* New Feature: Display NitroPack settings for Page Speed Boost users
* New Feature: Option to allow editors to purge cache
* Improvement: Move config file to default location for WP Engine clients
* Bug fix: Overall stability and fixes

Lack of Capability Check

If you were going to do basic security vetting of a WordPress plugin, one of the things you would do is to check to make sure AJAX accessible functions have been properly secured. This is one of the quick checks we do on a regular basis when there is an indication that a hacker is targeting a plugin, because improperly secured AJAX accessible functions are common source of serious vulnerabilities. That wasn’t done by WP Engine.

As an example of checking on that, let’s look a AJAX accessible function to disconnect from NitroPack’s service.

In the file main.php, the function is registered to accessible by anyone logged in to WordPress:

120
add_action('wp_ajax_nitropack_disconnect', 'nitropack_disconnect');

That registration only occurs if the function is_admin() is true:

111
if (is_admin()) {

That function tells you if an admin page is being accessed. Based on what is run there, it appears the developer was probably using that as intended, though they have also been confused and thought it told if the request is coming from an Administrator. The poorly named function was warned about years ago, but still hasn’t been addressed, despite repeated exploited vulnerabilities caused in part by that. (It is one of several unfixed security issues in WordPress.) That is something that Matt Mullenweg has the power to fix, but he hasn’t.

The function is located in the file functions.php. In the function, there should be a capability check before the disconnection happens. Here is the code at the beginning of the function:

2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
function nitropack_disconnect() {
    nitropack_verify_ajax_nonce($_REQUEST);
    nitropack_uninstall_advanced_cache();
 
    try {
        nitropack_event("disconnect");
        if (null !== $nitro = get_nitropack_sdk()) {
            nitropack_reset_webhooks($nitro);
        }
    } catch (\Exception $e) {
        nitropack_json_and_exit(array("status" => "error", "message" => $e->getMessage()));
    }

There isn’t a capability check there. Based on the name, the function nitropack_verify_ajax_nonce() would probably be doing another needed security check to prevent cross-site request forgery (CSRF). Sometimes developers include a capability check in a function like that. That function, which is in the same file, doesn’t include a capabilities check:

2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
function nitropack_verify_ajax_nonce($request_data) {
    // If not an ajax request
    if (!defined('DOING_AJAX') || !DOING_AJAX) {
        return;
    }
 
    // If nonce fails verification
    if (empty($request_data['nonce']) || !wp_verify_nonce($request_data['nonce'], NITROPACK_NONCE)) {
        wp_die('Unauthorized request');
    }
}

The nonce check to prevent CSRF there would normally limit who has access, though WordPress’ documentation warns against relying on that:

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.

This plugin is a good example of why there is that warning. It turns out the nonce value needed to pass the check is included on every admin page of WordPress.

That occurs in the following code:

1250
add_action('admin_enqueue_scripts', 'load_nitropack_scripts_styles');
1216
1217
1218
1219
1220
1221
1222
function load_nitropack_scripts_styles($page) {
    //global WP
    wp_enqueue_style('nitropack-notifications', plugin_dir_url(__FILE__) . 'view/stylesheet/nitro-notifications.min.css', array(), NITROPACK_VERSION);
    wp_enqueue_script('nitropack_notices_js', plugin_dir_url(__FILE__) . 'view/javascript/np_notices.js', array(), NITROPACK_VERSION, true);
    wp_localize_script('nitropack_notices_js', 'nitropack_notices_vars', array(
        'nonce' => wp_create_nonce(NITROPACK_NONCE),
    ));

So anyone logged in to WordPress is able to do the disconnection.

The problem isn’t limited to that function, there are numerous other AJAX accessible functions that lack the capability check. We didn’t look to see what all could be an attacker could accomplish with that.

Reviews Don’t Cost That Much

Even if WP Engine doesn’t have the in house capability to review the security of its plugins, it wouldn’t break the bank to have hired someone to do a review of the plugin. Our price for a review would be $500, which is less than it is cost than for one hour of the time of their lawyers in their current legal case with Matt Mullenweg and Automattic.

Long Time Issue

The issue has existed since the first release of the plugin in the WordPress plugin directory, back in August 2019. It was only in November of last year that the nonce check was added. For some reason WPScan and Wordfence claimed the capability check was added in when the nonce check was actually added.

Timeline

  • October 11 – NitroPack notified through security email address listed on their contact page.
  • October 17 – WP Engine’s VP of security responds that we “are working with the NitroPack engineers to resolve it soon.”

Proof of Concept

The following proof of concept will disconnect from NitroPack’s service, when logged in to WordPress.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[nonce]” with the value of “nonce” in the JavaScript variable var nitropack_notices_vars in the source code of admin pages of the website.

http://[path to WordPress]/wp-admin/admin-ajax.php?action=nitropack_disconnect&nonce=[nonce]

Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.

Plugin Security Scorecard Grade for WPScan

Checked on April 12, 2025
F

See issues causing the plugin to get less than A+ grade

Leave a Reply

Your email address will not be published.