Introduction
A flawed authorization check in the Users Manager PN plugin for WordPress lets completely unauthenticated attackers overwrite arbitrary user metadata on any account, which leads directly to full account takeover. The vulnerability has a CVSS score of 9.8, and the exploit requires nothing more than a single crafted HTTP request. Any WordPress site running the affected plugin is at serious risk.
The Users Manager PN plugin (slug: "userspn") is developed by Padres en la Nube and distributed through the official WordPress plugin repository. It adds user management features to WordPress sites. Its exact installation footprint is not publicly documented, but because it is listed on WordPress.org, any WordPress administrator searching for a user management plugin can find it.
Technical information
The vulnerability is in the userspn_ajax_nopriv_server() function in the file class-userspn-ajax-nopriv.php, in the code path that handles the userspn_form_save AJAX action. It is classified as CWE-862: Missing Authorization.
Root cause: flawed authorization conditional
The conditional that decides whether a request is permitted only blocks unauthenticated users when the user_id parameter is empty. When an attacker supplies a non-empty user_id value, execution skips this check entirely. The function then calls update_user_meta() without any authentication or authorization check on the requester.
Any visitor to the site can therefore send an AJAX request that targets any user account by ID and change that user's metadata fields at will.
Compounding factor: public nonce exposure
WordPress nonces are meant to be a secondary security mechanism that confirms a request came from a legitimate context. Here, the nonce the AJAX endpoint requires (identified as userspn-nonce) is exposed to every site visitor. The plugin registers it via wp_localize_script on the public wp_enqueue_scripts hook, so it is embedded in the page source for any unauthenticated visitor. As a security control, the nonce does nothing.
The relevant code is in the WordPress plugin repository at these locations:
- Authorization logic: class-userspn-ajax-nopriv.php, line 186
- Bypass path: class-userspn-ajax-nopriv.php, line 190
- Metadata update call: class-userspn-ajax-nopriv.php, line 233
- Nonce exposure: class-userspn-common.php, line 168
- Secret token handling: class-userspn-functions-user.php, line 235
Attack flow
Exploitation is straightforward:
- An unauthenticated attacker visits any page on the target WordPress site where the Users Manager PN plugin enqueues its scripts.
- The attacker extracts the
userspn-noncevalue from the page source, wherewp_localize_scripthas embedded it. - The attacker crafts an AJAX request to the
userspn_form_saveaction with a non-emptyuser_idparameter (for example, the administrator's user ID, which is commonly1on WordPress installations). - Because the
user_idis non-empty, the request skips the flawed authorization conditional entirely. - The nonce check passes, because the attacker already has the valid nonce from the public page.
- The function calls
update_user_meta()with attacker-controlled field names and values, updating the target user's metadata. - By overwriting the
userspn_secret_tokenfield (or other sensitive metadata), the attacker can take over the targeted account, including administrator accounts.
The attack needs no prior authentication, no special tooling, and no brute forcing. It is a single, well-formed HTTP request.
Affected systems and versions
All versions of the Users Manager PN plugin for WordPress up to and including version 1.1.15 are affected. The vulnerable code is present in both the tagged release (the source code references point to tag 1.0.31) and the trunk branch. The vendor has indicated that version 1.1.20 addresses the issue.
References
- Wordfence Vulnerability Advisory for CVE-2026-4003
- Source: class-userspn-ajax-nopriv.php (tag 1.0.31, line 186)
- Source: class-userspn-ajax-nopriv.php (tag 1.0.31, line 190)
- Source: class-userspn-ajax-nopriv.php (tag 1.0.31, line 233)
- Source: class-userspn-common.php (tag 1.0.31, line 168)
- Source: class-userspn-functions-user.php (tag 1.0.31, line 235)
- Source: class-userspn-ajax-nopriv.php (trunk, line 186)
- Source: class-userspn-ajax-nopriv.php (trunk, line 190)
- Source: class-userspn-ajax-nopriv.php (trunk, line 233)
- Source: class-userspn-common.php (trunk, line 168)
- Source: class-userspn-functions-user.php (trunk, line 235)
- Plugin Changeset



