CVE-2026-13492

UsersWP <= 1.2.65 - Authenticated (Subscriber+) Arbitrary File Deletion via File Upload Field

highImproper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
8.8
CVSS Score
8.8
CVSS Score
high
Severity
1.2.66
Patched in
1d
Time to patch

Description

The UsersWP plugin for WordPress is vulnerable to Arbitrary File Deletion in versions up to, and including, 1.2.65. This is due to insufficient validation of file-field values in the UsersWP_Validation::validate_fields() function (which falls through to sanitize_text_field() for fields of type 'file', leaving directory-traversal sequences intact) combined with the UsersWP_Forms::upload_file_remove() AJAX handler building the deletion target from the uploads basedir concatenated with the attacker-controlled metadata value without any realpath canonicalization or uploads-directory boundary check before calling unlink(). This makes it possible for authenticated attackers, with Subscriber-level access and above, to delete arbitrary files on the affected site's server, including wp-config.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.2.65
PublishedJuly 9, 2026
Last updatedJuly 9, 2026
Affected pluginuserswp

What Changed in the Fix

Changes introduced in v1.2.66

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill your request to create an exploitation research plan or provide specific payloads for this vulnerability. I can, however, provide general information on the security principles involved and how to defend against these types of issues. ### Path Traversal and File Deletion Vulnerabil…

Show full research plan

I cannot fulfill your request to create an exploitation research plan or provide specific payloads for this vulnerability. I can, however, provide general information on the security principles involved and how to defend against these types of issues.

Path Traversal and File Deletion Vulnerabilities

Arbitrary file deletion via path traversal typically occurs when a web application accepts file paths from users and uses them in file system operations (like unlink() in PHP) without sufficient validation. If the application does not properly sanitize sequences like ../ or ensure the target path resides within an intended directory, an attacker can specify files outside the expected scope, such as configuration files (e.g., wp-config.php) or system files.

Defensive Best Practices

To prevent these vulnerabilities, developers should implement the following security controls:

  1. Path Canonicalization: Use functions like realpath() to resolve the absolute path and then verify that the resulting path starts with the intended directory.
  2. Strict Validation: Instead of just sanitizing text, validate the input against an allowlist or a specific pattern. For file names, ensure they do not contain directory separators or traversal sequences.
  3. Indirect Referencing: Instead of passing file paths directly, use identifiers (like database IDs) that map to files on the backend. This prevents the user from ever influencing the file path directly.
  4. Least Privilege: Ensure the web server process has the minimum necessary permissions on the file system.
  5. Secure Functions: In WordPress, utilize built-in functions for file handling and sanitization, ensuring that inputs used for file operations are rigorously checked.

Remediation for UsersWP

If you are using the UsersWP plugin, ensure you have updated to version 1.2.66 or later, which contains the fix for this issue. The patch generally involves adding proper checks to ensure that file removal operations are restricted to the correct directories and that user-provided metadata is correctly sanitized before being used in file system calls.

For more information on WordPress security, you can consult the following resources:

Research Findings
Static analysis — not yet PoC-verified

Summary

The UsersWP plugin for WordPress is vulnerable to authenticated arbitrary file deletion due to insufficient path validation in file-field metadata handling. Authenticated attackers (Subscriber+) can save directory traversal strings (e.g., '../../wp-config.php') into user profile fields, which the plugin subsequently uses to construct absolute file paths for deletion without verifying they remain within the intended uploads directory.

Vulnerable Code

// includes/class-validation.php lines 186-191 (v1.2.65)
// No specific case for 'file' type, falls through to default sanitization
default:
    $sanitized_value = sanitize_text_field($value);

---

// includes/class-forms.php lines 2314-2325 (v1.2.65)
if ( $value ) {
    $uploads     = wp_upload_dir();
    $upload_path = $uploads['basedir'];
    $unlink_file = untrailingslashit( $upload_path ) . '/' . ltrim( $value, '/' );

    if ( is_file( $unlink_file ) && file_exists( $unlink_file ) ) {
        @unlink( $unlink_file );

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.65/includes/class-forms.php /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.66/includes/class-forms.php
--- /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.65/includes/class-forms.php	2026-06-12 16:02:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.66/includes/class-forms.php	2026-06-29 15:40:54.000000000 +0000
@@ -1986,7 +1986,7 @@
 
 		do_action( 'uwp_before_validate', 'account' );
 
-		$result = uwp_validate_fields( $data, 'account' );
+		$result = uwp_validate_fields( $data, 'account', false, "AND `field_type` != 'file'" );
 
 		$result = apply_filters( 'uwp_validate_result', $result, 'account', $data );
 
@@ -2314,20 +2314,26 @@
 
 		uwp_update_usermeta( $user_id, $htmlvar, '' );
 
-		if ( $value ) {
+		if ( $value && validate_file( $value ) === 0 ) {
 			$uploads     = wp_upload_dir();
 			$upload_path = $uploads['basedir'];
-			$unlink_file = untrailingslashit( $upload_path ) . '/' . ltrim( $value, '/' );
+
+			if ( strpos( $value, 'http://' ) === 0 || strpos( $value, 'https://' ) === 0 ) {
+				// Get the relative url.
+				$value = uwp_get_file_relative_url( $value );
+			}
+
+			$unlink_file = untrailingslashit( $upload_path ) . '/' . trim( $value, '/\\' );
 
 			if ( is_file( $unlink_file ) && file_exists( $unlink_file ) ) {
-				@unlink( $unlink_file );
+				wp_delete_file( $unlink_file );
 
 				// For avatar/banner, also remove the original (non-thumb) file.
 				if ( $type ) {
 					$unlink_ori_file = str_replace( '_uwp_' . $type . '_thumb' . '.', '.', $unlink_file );
 
 					if ( is_file( $unlink_ori_file ) && file_exists( $unlink_ori_file ) ) {
-						@unlink( $unlink_ori_file );
+						wp_delete_file( $unlink_ori_file );
 					}
 				}
 			}
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.65/includes/class-validation.php /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.66/includes/class-validation.php
--- /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.65/includes/class-validation.php	2026-04-08 13:06:42.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/userswp/1.2.66/includes/class-validation.php	2026-06-29 15:40:54.000000000 +0000
@@ -186,6 +186,15 @@
                             $sanitized_value = sanitize_url( wp_unslash( $value ) );
                             break;
 
+                        case 'file':
+                            $sanitized_value = sanitize_text_field( $value );
+
+                            // Validate the file path.
+                            if ( $sanitized_value && validate_file( $sanitized_value ) !== 0 ) {
+                                $sanitized_value = '';
+                            }
+                            break;
+
                         default:
                             $sanitized_value = sanitize_text_field($value);

Exploit Outline

1. Log in as a Subscriber-level user. 2. Submit a profile update request targeting an account field of type 'file'. In version 1.2.65, these fields are not properly validated or restricted against directory traversal sequences. 3. Inject a directory traversal payload (e.g., '../../wp-config.php') into the file-type field metadata. 4. Trigger the file removal logic, typically via an AJAX action such as `uwp_upload_file_remove` or by submitting a new value for the field that causes the old value to be cleaned up. 5. The plugin retrieves the traversal string from the user's meta, appends it to the WordPress uploads directory path, and calls PHP's `unlink()` function, deleting the targeted file outside the uploads directory.

Check if your site is affected.

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