WPMasterToolKit <= 2.14.0 - Missing Authorization
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:NTechnical Details
<=2.14.0What Changed in the Fix
Changes introduced in v2.14.1
Source Code
WordPress.org SVN# 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(fromWPMastertoolkit_Blacklisted_Usernames::ACTION) - Method: POST
- Authentication: Authenticated (Subscriber or higher)
- Vulnerable Parameter:
new_username(inferred) orusername(inferred) - Preconditions:
- The "Blacklisted Usernames" module must be active.
- An administrator account must exist with a username present in the
BLACKLISTarray (e.g.,admin).
3. Code Flow
- Registration: In
admin/modules/core/class-blacklisted-usernames.php, the__constructmethod registers the AJAX action:add_action( 'wp_ajax_' . self::ACTION, array( $this, 'change_admin_name' ) ); - Detection: The
admin_inithook triggerscheck_the_current_username(), which scans the database for users inself::BLACKLISTwho have theadministratorrole. - Execution: When a POST request is made to
admin-ajax.phpwith the actionwpmastertoolkit-blacklisted-usernames-action, the functionchange_admin_name()is executed. - Missing Check: The function
change_admin_name()likely verifies the noncewpmastertoolkit-blacklisted-usernames-noncebut fails to callcurrent_user_can(). It then proceeds to update theuser_loginof the identified administrator usingwp_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.
- 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.
- Accessing the Admin Area: A Subscriber can access
/wp-admin/profile.phpor/wp-admin/index.php. - 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_evalto extract the nonce:window.wpmtk_blacklisted_usernames?.nonce
- The script handle is
5. Exploitation Strategy
- Setup: Ensure an administrator user named
adminexists. - Login: Authenticate as a Subscriber-level user.
- Extract Nonce: Navigate to
/wp-admin/and extract thewpmastertoolkit-blacklisted-usernames-nonce. - Execute Attack: Send an AJAX request to rename the
adminuser.
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:
(Note:action=wpmastertoolkit-blacklisted-usernames-action&nonce=[EXTRACTED_NONCE]&new_username=renamed_admin_account&username=adminusernameandnew_usernameare inferred parameter names based on the function's purpose of renaming a specific blacklisted user to a new one).
6. Test Data Setup
- Plugin Installation: Install and activate
wpmastertoolkitv2.14.0. - Module Activation: Ensure "Blacklisted Usernames" is enabled in the toolkit settings.
- Target User: Create/Ensure a user exists with:
- Username:
admin - Role:
Administrator
- Username:
- Attacker User: Create a user with:
- Username:
attacker_sub - Password:
password123 - Role:
Subscriber
- Username:
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
adminwill have theiruser_loginchanged in thewp_userstable torenamed_admin_account. - Impact: The original administrator can no longer log in using the name
admin.
8. Verification Steps
- Check Database via WP-CLI:
Confirm thatwp user list --field=user_loginadminis no longer in the list andrenamed_admin_accountis present. - Check User ID:
Verify that the ID of the renamed user matches the original ID of theadminuser: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.
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
@@ -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.