Skip to main content
Vulnerability Database/CVE-2026-19991

CVE-2026-19991: UsersWP WordPress Path Traversal Flaw

CVE-2026-19991 is a path traversal vulnerability in UsersWP WordPress plugin that enables authenticated attackers to delete arbitrary files. This article covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-19991 Overview

CVE-2026-19991 is an arbitrary file deletion vulnerability in the UsersWP plugin for WordPress, affecting all versions up to and including 1.2.70. The flaw resides in the upload_file_remove() AJAX handler and stems from insufficient path validation in the uwp_get_file_relative_url() helper. Authenticated attackers with Subscriber-level access can delete arbitrary files on the underlying server, including wp-config.php. Deleting wp-config.php on a WordPress site typically triggers the setup wizard, which an attacker can use to connect the site to a database under their control and achieve remote code execution.

Critical Impact

Subscriber-level accounts can traverse outside the uploads directory and delete arbitrary files, enabling site takeover through wp-config.php removal.

Affected Products

  • WordPress UsersWP plugin versions up to and including 1.2.70
  • WordPress sites permitting user registration at Subscriber level or above
  • Deployments using UsersWP account form file upload fields

Discovery Timeline

  • 2026-09-11 - CVE-2026-19991 published to the National Vulnerability Database
  • 2026-09-11 - Last updated in NVD database

Technical Details for CVE-2026-19991

Vulnerability Analysis

The vulnerability is a path traversal issue [CWE-22] in the UsersWP account file handling logic. When a user submits an account form without a real $_FILES upload, process_account() calls uwp_validate_fields() and merges its result with the empty output of UsersWP_Files::validate_uploads(). This causes the plugin to accept the attacker-controlled file value directly from $_POST as a legitimate file reference.

At storage time the value is checked only with validate_file(), which returns success for any string that does not contain a literal ../ sequence. The stored value later flows into upload_file_remove(), where it is validated again with validate_file() and normalized through uwp_get_file_relative_url(). That helper performs a global str_replace() of the uploads base URL against the stored URL. A crafted value containing embedded ..<uploads-baseurl> tokens collapses into ../../ traversal sequences after the final validation check. The transformed path is appended to the uploads base directory and passed to wp_delete_file() without any canonical containment check.

Root Cause

The root cause is validation performed before normalization. validate_file() inspects the raw string for literal traversal sequences, but the subsequent str_replace() operation in uwp_get_file_relative_url() can introduce new ../ sequences that were previously hidden inside embedded copies of the uploads base URL. The design also lacks a realpath-based containment check to confirm the resolved file lives inside the uploads directory before deletion.

Attack Vector

An authenticated Subscriber submits a crafted request to the upload_file_remove() AJAX endpoint referencing a stored file value whose URL contains embedded copies of the uploads base URL wrapped around traversal tokens. After str_replace() collapses those tokens, the resulting relative path escapes the uploads directory. The attacker then targets sensitive files such as wp-config.php, .htaccess, or plugin PHP files. Deleting wp-config.php forces WordPress into its installation flow, which an attacker can hijack to point the site at an attacker-controlled database and execute arbitrary PHP.

Refer to the Wordfence Vulnerability Analysis and the UsersWP source in class-forms.php for the vulnerable code paths.

Detection Methods for CVE-2026-19991

Indicators of Compromise

  • POST requests to admin-ajax.php with action=uwp_upload_file_remove originating from low-privilege user sessions.
  • Request bodies containing repeated occurrences of the site uploads base URL concatenated with .. sequences inside the file parameter.
  • Unexpected deletion or absence of wp-config.php, .htaccess, or plugin bootstrap files, followed by WordPress redirecting visitors to /wp-admin/install.php.
  • New WordPress installation attempts pointing to remote or unknown database hosts.

Detection Strategies

  • Inspect web server access logs for uwp_upload_file_remove AJAX calls containing URL-encoded traversal patterns in POST bodies.
  • Enable file integrity monitoring on the WordPress document root to alert on deletion of core files, wp-config.php, and plugin PHP files.
  • Correlate Subscriber-level authentications with subsequent AJAX activity targeting UsersWP endpoints.

Monitoring Recommendations

  • Alert on any HTTP 200 response to admin-ajax.php where the request parameters reference the uploads base URL more than once.
  • Monitor filesystem audit logs (auditd, fs.notify) for unlink operations against files outside wp-content/uploads/.
  • Track appearance of the WordPress installation screen on production sites through synthetic monitoring.

How to Mitigate CVE-2026-19991

Immediate Actions Required

  • Update the UsersWP plugin to a version released after 1.2.70 that includes changeset 3650759.
  • Disable UsersWP temporarily on sites that cannot be patched immediately and that permit open registration.
  • Restrict new user registration to trusted roles or disable it entirely until patched.
  • Back up wp-config.php and confirm filesystem permissions restrict deletion by the web server user where operationally feasible.

Patch Information

The vendor addressed the issue in UsersWP changeset 3650759, which hardens validation in uwp_get_file_relative_url() and the upload_file_remove() handler. Site operators should upgrade to the fixed release published to the WordPress plugin repository and verify the installed version through the WordPress admin dashboard.

Workarounds

  • Apply a web application firewall rule blocking admin-ajax.php requests with action=uwp_upload_file_remove when the file parameter contains multiple instances of the uploads base URL.
  • Remove the Subscriber role's ability to submit UsersWP account form updates until the plugin is upgraded.
  • Set filesystem ownership so the web server user cannot delete wp-config.php or files outside wp-content/uploads/.
bash
# Example Nginx rule to block traversal patterns in the vulnerable AJAX action
if ($request_uri ~* "/wp-admin/admin-ajax\.php") {
    if ($request_body ~* "action=uwp_upload_file_remove.*(\.\./|%2e%2e%2f)") {
        return 403;
    }
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.