CVE-2026-12102

UsersWP <= 1.2.63 - Insecure Direct Object Reference to Authenticated (Editor+) Arbitrary User Avatar/Banner Reset via 'user_id' Parameter

lowAuthorization Bypass Through User-Controlled Key
2.7
CVSS Score
2.7
CVSS Score
low
Severity
1.2.64
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.2.63
PublishedJune 17, 2026
Last updatedJune 18, 2026
Affected pluginuserswp

What Changed in the Fix

Changes introduced in v1.2.64

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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 where UsersWP_Forms::handler is initialized).
  • Hook: Likely admin_init or init where UsersWP_Forms::handler() is registered.
  • Action: POST request with the parameter uwp_avatar_reset or uwp_banner_reset.
  • Vulnerable Parameter: user_id (passed via GET or POST).
  • Required Authentication: Authenticated (Editor or higher).
  • Preconditions: The target user (e.g., Administrator) must have an avatar or banner set in the uwp_usermeta table.

3. Code Flow

  1. Entry Point: A POST request is sent to an administrative page (e.g., /wp-admin/profile.php?user_id=1).
  2. Trigger: UsersWP_Forms::handler() in includes/class-forms.php checks for the presence of $_POST['uwp_avatar_reset'] or $_POST['uwp_banner_reset'].
  3. Vulnerable Call: handler() calls $this->process_image_reset( 'avatar' ) or $this->process_image_reset( 'banner' ).
  4. IDOR Sink: Inside process_image_reset(), the code extracts the target user_id from the request (likely $_GET['user_id'] or $_POST['user_id']).
  5. Authorization Failure: The function fails to verify if the current user has permission to modify the target user_id.
  6. Metadata Deletion: The function calls uwp_delete_usermeta( $user_id, 'avatar_thumb' ) or similar, clearing the data in the uwp_usermeta table.

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:

  1. Identify Action: The AJAX action uwp_ajax_image_crop_popup_form returns the HTML modal containing the required nonce.
  2. Navigate/Execute: Use the http_request tool to perform an authenticated AJAX call as the Editor.
  3. 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
    
  4. Extract Nonce: Parse the response HTML for the input field:
    <input type="hidden" name="uwp_reset_nonce" id="uwp_reset_nonce" value="[NONCE_VALUE]">
  5. JS Variable (Fallback): If the plugin localizes data, check window.uwp_localize_data using browser_eval.

5. Exploitation Strategy

  1. Authentication: Log in as a user with the Editor role.
  2. Target Identification: Identify the user_id of the target Administrator (usually 1).
  3. Nonce Retrieval: Perform the AJAX call described in Section 4 to obtain a valid uwp_reset_nonce.
  4. Exploit Request: Send a POST request to /wp-admin/profile.php targeting the Administrator.
    • URL: /wp-admin/profile.php?user_id=1
    • Method: POST
    • Body Parameters:
      • uwp_avatar_reset: 1
      • uwp_reset_nonce: [EXTRACTED_NONCE]
      • user_id: 1
  5. Headers: Ensure Cookie header for the Editor session is included.

6. Test Data Setup

  1. Target User: Ensure User ID 1 (Admin) exists.
  2. Avatar Metadata: Manually set or upload an avatar for User ID 1 so that the avatar_thumb key exists in the uwp_usermeta table.
    wp db query "INSERT INTO wp_uwp_usermeta (user_id, meta_key, meta_value) VALUES (1, 'avatar_thumb', 'https://example.com/avatar.jpg')"
    
  3. Attacker User: Create a user with the editor role.
    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
Research Findings
Static analysis — not yet PoC-verified

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

--- includes/class-forms.php
+++ includes/class-forms.php
@@ -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.