CVE-2026-39591 Overview
CVE-2026-39591 is an arbitrary file upload vulnerability in the WP-BusinessDirectory WordPress plugin affecting versions up to and including 4.0.0. The flaw is classified under CWE-434 (Unrestricted Upload of File with Dangerous Type). An authenticated attacker holding only Subscriber-level privileges can upload arbitrary files to the WordPress installation. Because Subscriber accounts are commonly open for self-registration on WordPress sites, the authentication barrier offers minimal protection. Successful exploitation enables remote code execution on the underlying web server.
Critical Impact
A Subscriber-level user can upload arbitrary files to a WordPress site running WP-BusinessDirectory <= 4.0.0, leading to remote code execution and full site compromise.
Affected Products
- WP-BusinessDirectory WordPress plugin versions <= 4.0.0
- WordPress installations with WP-BusinessDirectory enabled
- Sites permitting Subscriber-level account registration on vulnerable plugin versions
Discovery Timeline
- 2026-06-15 - CVE-2026-39591 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2026-39591
Vulnerability Analysis
The vulnerability resides in the file upload handling logic of the WP-BusinessDirectory plugin. The plugin exposes upload functionality to authenticated users but fails to enforce sufficient validation on file extensions, MIME types, or content. A Subscriber-level account, which is the lowest-privileged authenticated role in WordPress, can invoke the upload endpoint and place executable content within a web-accessible directory.
Once a malicious PHP file lands inside the WordPress uploads directory, the attacker requests it directly through HTTP. The web server executes the file in the context of the WordPress process, granting command execution on the host. From there, attackers typically pivot to database credential theft, persistence via web shells, and lateral movement.
The scope change captured in the CVSS vector reflects that an attacker compromising the WordPress instance can affect resources beyond the plugin itself, including the database, file system, and adjacent applications hosted on the same server.
Root Cause
The root cause is missing or insufficient validation on user-supplied uploads. The plugin does not restrict uploads to a safe allow-list of extensions and does not verify file content against the declared MIME type. Files with dangerous extensions such as .php, .phtml, or .phar are accepted and stored in a location where the web server interprets them as executable code.
Attack Vector
The attack is network-based and requires only Subscriber-level authentication. The attacker registers an account or uses existing credentials, authenticates to WordPress, and sends a crafted multipart upload request to the plugin endpoint. The uploaded payload is a PHP file containing attacker-controlled code. The attacker then issues a direct HTTP request to the uploaded file path, triggering code execution. No user interaction is required beyond the initial authentication.
No public proof-of-concept code has been published. Refer to the Patchstack WordPress Vulnerability Report for advisory details.
Detection Methods for CVE-2026-39591
Indicators of Compromise
- Files with executable extensions such as .php, .phtml, .phar, or .htaccess present in the WordPress wp-content/uploads/ directory or WP-BusinessDirectory upload paths.
- HTTP POST requests to WP-BusinessDirectory upload endpoints originating from accounts with the Subscriber role.
- Outbound network connections from the web server process (php-fpm, apache2, httpd) to unfamiliar external hosts shortly after a Subscriber upload event.
- New or unexpected WordPress administrator accounts created after a Subscriber upload.
Detection Strategies
- Monitor file creation events in WordPress upload directories and alert on any file written with an executable extension.
- Inspect web server access logs for direct GET requests to files inside wp-content/uploads/ that resolve to PHP content.
- Correlate Subscriber-account authentication events with subsequent file upload requests and child process creation by the web server.
- Run integrity scans against the WordPress installation to identify newly introduced PHP files outside the core, theme, and plugin baselines.
Monitoring Recommendations
- Enable WordPress audit logging to track user role activity, file uploads, and privilege changes.
- Forward web server logs and WordPress audit logs to a centralized analytics platform for retention and correlation.
- Alert on web server processes spawning shell interpreters such as sh, bash, or python immediately after an upload request.
How to Mitigate CVE-2026-39591
Immediate Actions Required
- Update WP-BusinessDirectory to a version newer than 4.0.0 as soon as a patched release is available from the vendor.
- Disable open user registration in WordPress settings, or restrict the default role for new registrations away from Subscriber if the plugin is required.
- Audit existing Subscriber accounts and remove any that are unrecognized or inactive.
- Scan wp-content/uploads/ and plugin-specific upload directories for unexpected executable files and remove them.
Patch Information
Consult the Patchstack WordPress Vulnerability Report for current patch availability and remediation guidance. Apply the vendor-supplied fix once published and confirm the plugin version after the upgrade.
Workarounds
- Deactivate and remove the WP-BusinessDirectory plugin until a patched version is installed if the plugin is not business-critical.
- Block PHP execution within wp-content/uploads/ using web server configuration directives that deny script handling in upload directories.
- Deploy a Web Application Firewall (WAF) rule to block multipart uploads containing executable extensions to plugin endpoints.
- Restrict access to WordPress administrative and plugin endpoints by IP allow-list where operationally feasible.
# Example Apache configuration to deny PHP execution in WordPress uploads
<Directory "/var/www/html/wp-content/uploads">
<FilesMatch "\.(php|phtml|phar|php[0-9]+)$">
Require all denied
</FilesMatch>
</Directory>
# Equivalent nginx location block
location ~* /wp-content/uploads/.*\.(php|phtml|phar|php[0-9]+)$ {
deny all;
return 403;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

