CVE-2026-24388

WPMasterToolKit <= 2.14.0 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.14.1
Patched in
14d
Time to patch

Description

The WPMasterToolKit (WPMTK) – All in one plugin plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.14.0. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.14.0
PublishedJanuary 15, 2026
Last updatedJanuary 28, 2026
Affected pluginwpmastertoolkit

What Changed in the Fix

Changes introduced in v2.14.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-24388 ## 1. Vulnerability Summary The **WPMasterToolKit (WPMTK)** plugin (versions up to 2.14.0) contains a missing authorization vulnerability in its "Blacklisted Usernames" module. The plugin registers an AJAX action `wpmastertoolkit-blacklisted-usernames-a…

Show full research plan

Exploitation Research Plan - CVE-2026-24388

1. Vulnerability Summary

The WPMasterToolKit (WPMTK) plugin (versions up to 2.14.0) contains a missing authorization vulnerability in its "Blacklisted Usernames" module. The plugin registers an AJAX action wpmastertoolkit-blacklisted-usernames-action intended to allow administrators to rename accounts that use insecure, blacklisted usernames (like admin, root, etc.).

Because the handler is registered via wp_ajax_ without an internal capability check (like current_user_can('manage_options')), any authenticated user, including those with Subscriber privileges, can trigger the renaming logic. This allows a low-privileged user to rename administrative accounts, potentially causing denial of service or administrative confusion.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wpmastertoolkit-blacklisted-usernames-action (from WPMastertoolkit_Blacklisted_Usernames::ACTION)
  • Method: POST
  • Authentication: Authenticated (Subscriber or higher)
  • Vulnerable Parameter: new_username (inferred) or username (inferred)
  • Preconditions:
    1. The "Blacklisted Usernames" module must be active.
    2. An administrator account must exist with a username present in the BLACKLIST array (e.g., admin).

3. Code Flow

  1. Registration: In admin/modules/core/class-blacklisted-usernames.php, the __construct method registers the AJAX action:
    add_action( 'wp_ajax_' . self::ACTION, array( $this, 'change_admin_name' ) );
    
  2. Detection: The admin_init hook triggers check_the_current_username(), which scans the database for users in self::BLACKLIST who have the administrator role.
  3. Execution: When a POST request is made to admin-ajax.php with the action wpmastertoolkit-blacklisted-usernames-action, the function change_admin_name() is executed.
  4. Missing Check: The function change_admin_name() likely verifies the nonce wpmastertoolkit-blacklisted-usernames-nonce but fails to call current_user_can(). It then proceeds to update the user_login of the identified administrator using wp_update_user() or a direct database query.

4. Nonce Acquisition Strategy

The nonce is generated using self::NONCE (wpmastertoolkit-blacklisted-usernames-nonce). It is enqueued in show_notice_to_change_username() and localized for the administrative interface.

  1. Triggering Enqueue: The script and nonce are enqueued when an administrator with a blacklisted name is detected. However, since the AJAX action is available to all users, we must check if the nonce is localized globally in the admin area or only when the notice is shown.
  2. Accessing the Admin Area: A Subscriber can access /wp-admin/profile.php or /wp-admin/index.php.
  3. Extraction via Browser:
    • The script handle is wpmastertoolkit-blacklisted-usernames-admin.
    • The localized object is likely wpmtk_blacklisted_usernames (inferred from plugin naming conventions).
    • Use browser_eval to extract the nonce:
      window.wpmtk_blacklisted_usernames?.nonce
      

5. Exploitation Strategy

  1. Setup: Ensure an administrator user named admin exists.
  2. Login: Authenticate as a Subscriber-level user.
  3. Extract Nonce: Navigate to /wp-admin/ and extract the wpmastertoolkit-blacklisted-usernames-nonce.
  4. Execute Attack: Send an AJAX request to rename the admin user.

HTTP Request (via http_request tool):

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=wpmastertoolkit-blacklisted-usernames-action&nonce=[EXTRACTED_NONCE]&new_username=renamed_admin_account&username=admin
    
    (Note: username and new_username are inferred parameter names based on the function's purpose of renaming a specific blacklisted user to a new one).

6. Test Data Setup

  1. Plugin Installation: Install and activate wpmastertoolkit v2.14.0.
  2. Module Activation: Ensure "Blacklisted Usernames" is enabled in the toolkit settings.
  3. Target User: Create/Ensure a user exists with:
    • Username: admin
    • Role: Administrator
  4. Attacker User: Create a user with:
    • Username: attacker_sub
    • Password: password123
    • Role: Subscriber

7. Expected Results

  • Response: The AJAX handler should return a success status (likely JSON {"success": true} or a string "1").
  • Effect: The user with the login admin will have their user_login changed in the wp_users table to renamed_admin_account.
  • Impact: The original administrator can no longer log in using the name admin.

8. Verification Steps

  1. Check Database via WP-CLI:
    wp user list --field=user_login
    
    Confirm that admin is no longer in the list and renamed_admin_account is present.
  2. Check User ID:
    Verify that the ID of the renamed user matches the original ID of the admin user:
    wp user get renamed_admin_account --field=ID
    

9. Alternative Approaches

If the new_username parameter name is incorrect, examine the localized script admin/assets/build/core/blacklisted-usernames.js (if accessible) to find the exact key-value pairs sent in the jQuery.post or fetch request.

If the nonce is only localized for administrators, the exploit might require the Subscriber to find another way to trigger the notice, or the plugin might define the nonce globally via a main toolkit initialization script like wpmastertoolkit-admin. Check window.wpmastertoolkit_settings or similar global objects.

Research Findings
Static analysis — not yet PoC-verified

Summary

The WPMasterToolKit plugin for WordPress is vulnerable to unauthorized access due to a missing capability check in its 'Blacklisted Usernames' module. Authenticated users with Subscriber-level permissions or higher can exploit this to rename administrative accounts that use common, blacklisted usernames (such as 'admin' or 'root'), potentially leading to a denial of service for site administrators.

Vulnerable Code

// admin/modules/core/class-blacklisted-usernames.php line 136
    /**
     * Change admin name
     */
    public function change_admin_name() {

        $nonce    = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
        $username = sanitize_text_field( wp_unslash( $_POST['username'] ?? '' ) );
        if ( ! wp_verify_nonce( $nonce, self::NONCE ) || empty( $username ) ) {
            wp_send_json_error( array( 'message' => __( 'Invalid request.', 'wpmastertoolkit' ) ) );
        }

        $newusername = sanitize_text_field( wp_unslash( $_POST['new_username'] ?? '' ) );
        if ( empty( $newusername ) || in_array( $newusername, self::BLACKLIST ) ) {
            wp_send_json_error( array( 'message' => __( 'The new username is invalid or blacklisted.', 'wpmastertoolkit' ) ) );
        }

        $admin_user = get_user_by( 'login', $username );
        if ( empty( $admin_user ) ) {
            wp_send_json_error( array( 'message' => __( 'Admin user not found.', 'wpmastertoolkit' ) ) );
        }

        global $wpdb;
		//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $wpdb->update( $wpdb->users, array( 'user_login' => $newusername ), array( 'ID' => $admin_user->ID ) );

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/wpmastertoolkit/2.14.0/admin/modules/core/class-blacklisted-usernames.php	2025-02-27 16:10:52.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wpmastertoolkit/2.14.1/admin/modules/core/class-blacklisted-usernames.php	2025-12-26 11:39:14.000000000 +0000
@@ -136,6 +136,11 @@
      */
     public function change_admin_name() {
 
+        // Check if user has admin capabilities
+        if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'manage_users' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'wpmastertoolkit' ) ) );
+        }
+
         $nonce    = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
         $username = sanitize_text_field( wp_unslash( $_POST['username'] ?? '' ) );
         if ( ! wp_verify_nonce( $nonce, self::NONCE ) || empty( $username ) ) {
@@ -176,6 +181,12 @@
             );
         }
 
+        // Verify the target user is an administrator
+        $user_roles = $admin_user->roles ?? array();
+        if ( ! in_array( 'administrator', $user_roles ) ) {
+            wp_send_json_error( array( 'message' => __( 'This action can only be performed on administrator accounts.', 'wpmastertoolkit' ) ) );
+        }
+
         global $wpdb;
 		//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
         $wpdb->update( $wpdb->users, array( 'user_login' => $newusername ), array( 'ID' => $admin_user->ID ) );

Exploit Outline

To exploit this vulnerability, an attacker first authenticates as a Subscriber-level user. They must identify a site administrator whose username is on the plugin's predefined blacklist (e.g., 'admin'). The attacker then retrieves a valid nonce for the 'wpmastertoolkit-blacklisted-usernames-nonce' action, which is typically localized in the WordPress admin area scripts. Finally, the attacker sends a POST request to /wp-admin/admin-ajax.php with the 'action' set to 'wpmastertoolkit-blacklisted-usernames-action', the target's current 'username', and a 'new_username'. Because the server-side handler lacks a capability check (current_user_can), it will update the database and rename the administrator's account, preventing them from logging in with their original credentials.

Check if your site is affected.

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