CVE-2026-2001

WowRevenue <= 2.1.3 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Plugin Installation/Activation

highMissing Authorization
8.8
CVSS Score
8.8
CVSS Score
high
Severity
2.1.4
Patched in
1d
Time to patch

Description

The WowRevenue plugin for WordPress is vulnerable to unauthorized plugin installation due to a missing capability check in the 'Notice::install_activate_plugin' function in all versions up to, and including, 2.1.3. This makes it possible for authenticated attackers, with subscriber-level access and above, to install arbitrary plugins on the affected site's server which may make remote code execution possible.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=2.1.3
PublishedFebruary 16, 2026
Last updatedFebruary 16, 2026
Affected pluginrevenue

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2026-2001**, a missing authorization vulnerability in the WowRevenue plugin that allows Subscriber-level users to install and activate arbitrary plugins. --- ### 1. Vulnerability Summary The **WowRevenue – Product Bundles & Bulk Discounts** plugin (slug: `revenue`)…

Show full research plan

This research plan targets CVE-2026-2001, a missing authorization vulnerability in the WowRevenue plugin that allows Subscriber-level users to install and activate arbitrary plugins.


1. Vulnerability Summary

The WowRevenue – Product Bundles & Bulk Discounts plugin (slug: revenue) contains a vulnerability in the Notice::install_activate_plugin function. The function is intended to facilitate the installation of recommended or required plugins via an admin notice. However, it fails to perform a capability check (e.g., current_user_can( 'install_plugins' )), allowing any authenticated user—including those with the subscriber role—to trigger the installation and activation of any plugin from the WordPress.org repository. This can lead to Remote Code Execution (RCE) if an attacker installs a plugin with file management or command execution capabilities.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: revenue_install_activate_plugin (Inferred based on the class Notice and the function name install_activate_plugin. The slug revenue is the plugin's namespace).
  • HTTP Method: POST
  • Payload Parameters:
    • action: revenue_install_activate_plugin (Inferred)
    • slug: The slug of the target plugin to install (e.g., wp-file-manager or hello-dolly).
    • _wpnonce: A nonce likely required by the handler.
  • Authentication: Authenticated, Subscriber role or higher.
  • Preconditions: The plugin revenue must be active. The attacker must have a valid session cookie for a Subscriber user.

3. Code Flow

  1. Entry Point: An AJAX request is sent to admin-ajax.php with the action parameter.
  2. Hook Registration: The plugin likely registers the handler in a constructor or initialization method within the Notice class:
    add_action( 'wp_ajax_revenue_install_activate_plugin', [ $this, 'install_activate_plugin' ] );
  3. Vulnerable Function: Notice::install_activate_plugin is called.
  4. Missing Check: The function likely calls check_ajax_referer for CSRF protection but omits a call to current_user_can().
  5. Sink: The function uses the WordPress Plugin API (typically plugins_api()) to retrieve plugin data and uses a Plugin_Upgrader instance to download, install, and subsequently activate the plugin via activate_plugin().

4. Nonce Acquisition Strategy

The nonce is likely localized for the WordPress admin area to support notice-based actions.

  1. Access Admin: Even a Subscriber has access to wp-admin/profile.php.
  2. Identify Variable: Look for wp_localize_script output in the page source.
    • Inferred Script Handle: revenue-admin or revenue-notice.
    • Inferred Object Name: revenue_params or wow_revenue_obj.
    • Inferred Key: nonce or install_nonce.
  3. Strategy:
    • Login as a Subscriber.
    • Navigate to /wp-admin/profile.php.
    • Use browser_eval to extract the nonce:
      browser_eval("window.revenue_params?.nonce || window.revenue_obj?.nonce")
    • Note: If the nonce is strictly for the revenue_install_activate_plugin action, it might be named specifically (e.g., window.revenue_params?.install_plugin_nonce).

5. Exploitation Strategy

The goal is to install and activate the hello-dolly plugin (as a benign proof-of-concept) or wp-file-manager (to demonstrate high impact).

  1. Step 1: Authenticate: Log in as the Subscriber user.
  2. Step 2: Nonce Extraction: Navigate to /wp-admin/ and extract the nonce using the logic in Section 4.
  3. Step 3: Trigger Installation: Send a POST request to admin-ajax.php.
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      action=revenue_install_activate_plugin&slug=hello-dolly&_wpnonce=[EXTRACTED_NONCE]
      
  4. Step 4: Verify Activation: The server response should indicate success (likely a JSON object or 1).

6. Test Data Setup

  1. Target Plugin: Ensure revenue version 2.1.3 is installed and active.
  2. Attacker Account: Create a user with the Subscriber role:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
  3. Target for Installation: Ensure the target plugin (e.g., hello-dolly) is not currently installed.
    wp plugin delete hello-dolly

7. Expected Results

  • HTTP Response: A successful response (HTTP 200) with a body indicating the plugin was installed/activated (e.g., {"success":true} or true).
  • System State: The wp-content/plugins/hello-dolly/ directory should be created, and the plugin should appear as "Active" in the WordPress database.

8. Verification Steps

After the exploit attempt, use WP-CLI to confirm the change:

  1. Check Installation:
    wp plugin is-installed hello-dolly && echo "Plugin Installed"
  2. Check Activation:
    wp plugin is-active hello-dolly && echo "Plugin Active"
  3. Audit Logs (Optional): Check the wp_options table for the active plugins list:
    wp option get active_plugins

9. Alternative Approaches

  • Different Action Names: If revenue_install_activate_plugin fails, search the plugin files for the string install_activate_plugin to find the exact hook:
    grep -r "install_activate_plugin" /var/www/html/wp-content/plugins/revenue/
  • Missing Nonce: Try the request without a nonce. Some plugins use admin_init hooks to handle "notice" clicks without strict nonce verification for certain roles.
  • Activation Only: If installation is blocked by filesystem permissions but the plugin is already present (but inactive), check if the same endpoint can be used to activate it, which might bypass different sets of checks.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WowRevenue plugin for WordPress is vulnerable to unauthorized plugin installation and activation due to a missing capability check in the 'Notice::install_activate_plugin' AJAX function. This allow authenticated users with Subscriber-level permissions to install and activate any plugin from the WordPress repository by providing its slug, potentially leading to Remote Code Execution (RCE).

Vulnerable Code

// File: revenue/includes/classes/Notice.php (Inferred)
public function install_activate_plugin() {
    check_ajax_referer( 'revenue_nonce', 'nonce' );

    // Vulnerable: No current_user_can('install_plugins') check performed
    $slug = sanitize_text_field( $_POST['slug'] );

    include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    include_once ABSPATH . 'wp-admin/includes/plugin-install.php';

    $api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) );
    $upgrader = new Plugin_Upgrader( new WP_Ajax_Upgrader_Skin() );
    $result = $upgrader->install( $api->download_link );

    if ( $result ) {
        activate_plugin( $slug );
        wp_send_json_success();
    }
    wp_send_json_error();
}

Security Fix

--- a/includes/classes/Notice.php
+++ b/includes/classes/Notice.php
@@ -124,6 +124,10 @@
 	public function install_activate_plugin() {
 		check_ajax_referer( 'revenue_nonce', 'nonce' );
 
+		if ( ! current_user_can( 'install_plugins' ) ) {
+			wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions', 'revenue' ) ) );
+		}
+
 		$slug = isset( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : '';
 		if ( empty( $slug ) ) {
 			wp_send_json_error( array( 'message' => esc_html__( 'Invalid slug', 'revenue' ) ) );

Exploit Outline

1. Authenticate to the WordPress site as a user with Subscriber privileges. 2. Navigate to any wp-admin page (e.g., profile.php) and extract the AJAX nonce, typically localized in the page source under a variable like 'revenue_params'. 3. Send a POST request to '/wp-admin/admin-ajax.php' with the following body parameters: 'action=revenue_install_activate_plugin', 'slug=[TARGET_PLUGIN_SLUG]' (e.g., 'wp-file-manager'), and '_wpnonce=[EXTRACTED_NONCE]'. 4. Upon receiving the request, the server-side handler will execute the WordPress Plugin API to download and activate the specified plugin without verifying the user's role. 5. Verify successful exploitation by checking if the target plugin is active in the WordPress plugins list.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.