UsersWP <= 1.2.63 - Insecure Direct Object Reference to Authenticated (Editor+) Arbitrary User Avatar/Banner Reset via 'user_id' Parameter
Description
The UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.2.63 via the 'user_id' parameter due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with editor-level access and above, to reset and permanently delete the avatar or banner image of any arbitrary user, including administrators, by clearing their avatar_thumb or banner_thumb metadata in the uwp_usermeta table.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v1.2.64
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-12102 ## 1. Vulnerability Summary The **UsersWP** plugin (<= 1.2.63) contains an **Insecure Direct Object Reference (IDOR)** vulnerability in its profile image reset logic. Specifically, the `UsersWP_Forms::process_image_reset` function (called via `UsersWP_F…
Show full research plan
Exploitation Research Plan - CVE-2026-12102
1. Vulnerability Summary
The UsersWP plugin (<= 1.2.63) contains an Insecure Direct Object Reference (IDOR) vulnerability in its profile image reset logic. Specifically, the UsersWP_Forms::process_image_reset function (called via UsersWP_Forms::handler) fails to perform adequate authorization checks when determining which user's avatar or banner should be reset.
While the sister function process_image_crop (found in includes/class-forms.php) contains a check for manage_options when a user_id is provided, the reset functionality apparently lacks this restriction or uses a lower capability check (sufficient for an Editor), allowing any authenticated user with Editor-level access to clear the avatar_thumb or banner_thumb metadata for any other user, including Administrators.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/profile.php(or any admin-side page whereUsersWP_Forms::handleris initialized). - Hook: Likely
admin_initorinitwhereUsersWP_Forms::handler()is registered. - Action:
POSTrequest with the parameteruwp_avatar_resetoruwp_banner_reset. - Vulnerable Parameter:
user_id(passed viaGETorPOST). - Required Authentication: Authenticated (Editor or higher).
- Preconditions: The target user (e.g., Administrator) must have an avatar or banner set in the
uwp_usermetatable.
3. Code Flow
- Entry Point: A
POSTrequest is sent to an administrative page (e.g.,/wp-admin/profile.php?user_id=1). - Trigger:
UsersWP_Forms::handler()inincludes/class-forms.phpchecks for the presence of$_POST['uwp_avatar_reset']or$_POST['uwp_banner_reset']. - Vulnerable Call:
handler()calls$this->process_image_reset( 'avatar' )or$this->process_image_reset( 'banner' ). - IDOR Sink: Inside
process_image_reset(), the code extracts the targetuser_idfrom the request (likely$_GET['user_id']or$_POST['user_id']). - Authorization Failure: The function fails to verify if the current user has permission to modify the target
user_id. - Metadata Deletion: The function calls
uwp_delete_usermeta( $user_id, 'avatar_thumb' )or similar, clearing the data in theuwp_usermetatable.
4. Nonce Acquisition Strategy
The reset operation is protected by a nonce check. Based on templates/bootstrap/modal-profile-image.php, the nonce is generated using wp_create_nonce( 'uwp_reset_nonce_' . $type ).
Step-by-Step Acquisition:
- Identify Action: The AJAX action
uwp_ajax_image_crop_popup_formreturns the HTML modal containing the required nonce. - Navigate/Execute: Use the
http_requesttool to perform an authenticated AJAX call as the Editor. - AJAX Request:
POST /wp-admin/admin-ajax.php Content-Type: application/x-www-form-urlencoded action=uwp_ajax_image_crop_popup_form&type=avatar&style=bootstrap - Extract Nonce: Parse the response HTML for the input field:
<input type="hidden" name="uwp_reset_nonce" id="uwp_reset_nonce" value="[NONCE_VALUE]"> - JS Variable (Fallback): If the plugin localizes data, check
window.uwp_localize_datausingbrowser_eval.
5. Exploitation Strategy
- Authentication: Log in as a user with the Editor role.
- Target Identification: Identify the
user_idof the target Administrator (usually1). - Nonce Retrieval: Perform the AJAX call described in Section 4 to obtain a valid
uwp_reset_nonce. - Exploit Request: Send a
POSTrequest to/wp-admin/profile.phptargeting the Administrator.- URL:
/wp-admin/profile.php?user_id=1 - Method:
POST - Body Parameters:
uwp_avatar_reset:1uwp_reset_nonce:[EXTRACTED_NONCE]user_id:1
- URL:
- Headers: Ensure
Cookieheader for the Editor session is included.
6. Test Data Setup
- Target User: Ensure User ID 1 (Admin) exists.
- Avatar Metadata: Manually set or upload an avatar for User ID 1 so that the
avatar_thumbkey exists in theuwp_usermetatable.wp db query "INSERT INTO wp_uwp_usermeta (user_id, meta_key, meta_value) VALUES (1, 'avatar_thumb', 'https://example.com/avatar.jpg')" - Attacker User: Create a user with the
editorrole.wp user create attacker attacker@example.com --role=editor --user_pass=password123
7. Expected Results
- The server should respond with a redirect or a success message (`Avatar
Summary
The UsersWP plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) in versions up to 1.2.63. This allows authenticated attackers with Editor-level access or higher to reset the avatar or banner of any arbitrary user, including administrators, by manipulating the 'user_id' parameter.
Vulnerable Code
// includes/class-forms.php, line 76 } elseif ( isset( $_POST['uwp_avatar_reset'] ) ) { $errors = $this->process_image_reset( 'avatar' ); if ( ! is_wp_error( $errors ) ) { $redirect = $errors; } $message = __( 'Avatar reset successfully.', 'userswp' ); $processed = true; } elseif ( isset( $_POST['uwp_banner_reset'] ) ) { $errors = $this->process_image_reset( 'banner' ); if ( ! is_wp_error( $errors ) ) { $redirect = $errors; } $message = __( 'Banner reset successfully.', 'userswp' ); $processed = true; } --- // includes/class-forms.php (Inferred vulnerable implementation of process_image_reset) public function process_image_reset( $type = 'avatar' ) { if ( ! is_user_logged_in() ) { return false; } if ( empty( $_POST['uwp_reset_nonce'] ) || ! wp_verify_nonce( $_POST['uwp_reset_nonce'], 'uwp_reset_nonce_' . $type ) ) { return; } // Vulnerable: user_id is taken from request without verifying permissions to edit the specific user $user_id = ! empty( $_REQUEST['user_id'] ) ? absint( $_REQUEST['user_id'] ) : get_current_user_id(); $current_field = 'avatar' === $type ? 'avatar_thumb' : 'banner_thumb'; return uwp_delete_usermeta( $user_id, $current_field ); }
Security Fix
@@ -200,6 +200,16 @@ public function process_image_reset( $type = 'avatar' ) { if ( ! is_user_logged_in() ) { return false; } if ( empty( $_POST['uwp_reset_nonce'] ) || ! wp_verify_nonce( $_POST['uwp_reset_nonce'], 'uwp_reset_nonce_' . $type ) ) { return; } - $user_id = ! empty( $_REQUEST['user_id'] ) ? absint( $_REQUEST['user_id'] ) : get_current_user_id(); + if ( is_admin() && current_user_can( 'manage_options' ) && ! empty( $_REQUEST['user_id'] ) ) { + $user_id = absint( $_REQUEST['user_id'] ); + } else { + $user_id = get_current_user_id(); + } $current_field = 'avatar' === $type ? 'avatar_thumb' : 'banner_thumb';
Exploit Outline
The exploit methodology targets the UsersWP profile reset logic through an administrative endpoint. 1. Authenticate as a user with Editor-level privileges (who have access to the admin dashboard but normally cannot edit administrator profiles). 2. Acquire a valid 'uwp_reset_nonce' by triggering the AJAX action 'uwp_ajax_image_crop_popup_form' with the target 'type' (avatar or banner). The server returns the HTML for a modal containing the hidden nonce field. 3. Identify the 'user_id' of the target user (e.g., User ID 1 for the site administrator). 4. Submit a POST request to '/wp-admin/profile.php' (or similar admin-side profile pages) containing the parameter 'uwp_avatar_reset=1' (or 'uwp_banner_reset=1'), the targeted 'user_id', and the acquired 'uwp_reset_nonce'. 5. Because the vulnerable function prioritizes the 'user_id' from the request without validating if the current user has 'manage_options' capabilities for that specific ID, the plugin deletes the target user's 'avatar_thumb' or 'banner_thumb' metadata.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.