Introduction
An unauthenticated path traversal flaw in the MW WP Form WordPress plugin lets attackers move arbitrary files on the server into the public uploads directory, including critical configuration files like wp-config.php. With roughly 200,000 active installations exposed and no authentication required, this vulnerability is a significant risk to the WordPress ecosystem.
MW WP Form is a popular contact form builder plugin for WordPress, developed by web soudan and inc2734. It is widely used across Japanese and international WordPress deployments and supports form creation with file uploads and database storage of inquiry data. Its large install base and deep integration with WordPress file handling make vulnerabilities in this plugin especially damaging.
Technical Information
Root Cause: path_join() and Unsanitized Upload Field Keys
The vulnerability (classified as CWE-22, Path Traversal) comes from a misunderstanding of how WordPress's path_join() function behaves. When path_join() receives an absolute path as its second argument, it returns that absolute path unchanged and discards the first argument (the intended base directory) entirely. The MW WP Form plugin relied on path_join() to keep file operations inside a designated upload directory, but never validated that the input to path_join() was a relative path.
The generate_user_file_dirpath() function in classes/models/class.directory.php accepts a $name parameter (the upload field key) and passes it directly to path_join() alongside the intended user directory. If $name is an absolute path like /var/www/html/wordpress/wp-config.php, the function returns that absolute path verbatim.
Attack Flow
The attack moves through the plugin's data model and file handling pipeline in four steps:
- Injection via POST parameter. The attacker submits a crafted POST request to a form that uses MW WP Form. The
mwf_upload_files[]parameter contains an absolute filesystem path (e.g.,/var/www/html/wordpress/wp-config.php) as a key value. No authentication is required. - Data model ingestion. The plugin's Data model loads the submitted parameters via the
_set_request_valiables()function. The attacker-controlled key enters the plugin's internal data structures without sanitization. - Key iteration and path resolution. During form processing,
regenerate_upload_file_keys()inclass.data.phpiterates over the upload file keys and callsgenerate_user_filepath()with the attacker-supplied key as the$nameargument. The key survives validation because the targeted file exists at the specified absolute path. - File relocation. The
_get_attachments()method re-reads the surviving keys and passes the resolved absolute file path tomove_temp_file_to_upload_dir(). This function calls PHP'srename(), which physically moves the targeted file from its original location into the WordPress uploads folder.
Why the Previous Fix (5.1.1) Was Insufficient
This vulnerability bypasses the fix that version 5.1.1 introduced for the related CVE-2026-4347. That earlier patch hardened the generate_user_filepath() function, but the attacker-controlled upload field key still flowed unchecked into generate_user_file_dirpath(). The regenerate_upload_file_keys() function in class.data.php iterated over these keys without proper sanitization, so an attacker could bypass the 5.1.1 path traversal mitigations through this alternative code path.
Exploitation Preconditions
Two conditions must be met for successful exploitation:
- A file upload field must be actively present on the targeted form.
- The "Saving inquiry data in database" option must be enabled for that form.
If either condition is absent, the vulnerable code path is not reachable.
Patch Information
A public patch is available in MW WP Form version 5.1.2, released on April 8, 2026. The fix was merged via Pull Request #32 from the security/fix-file-upload-path-validation branch, authored by Kazuto Takeshita, in commit f872ab18ca670f5867b2241745daa30cd0fab861. The commit touches seven files with 203 additions and 20 deletions, and the security-critical logic is concentrated in classes/models/class.directory.php.
Defense in Depth: Three New Validation Methods
The 5.1.2 patch introduces three new protected static methods in class.directory.php:
_is_valid_path_segment($value)is a strict gatekeeper. It rejects any path component that is empty, contains null bytes (\0), equals.or.., is an absolute path, or does not match its ownwp_basename()(meaning it contains directory separators). The patch applies this check to both the$nameand$filenameparameters before either can influence any file system path._is_within_expected_dir_candidate($form_id, $path)independently reconstructs what the legitimate user temp directory should be, then verifies that the candidate path either matches it exactly or begins with it (plus a trailing slash). This containment check is what defeats thepath_join()absolute path bypass._get_expected_user_dir($form_id, $base_dir)independently computes the expected user directory from the CSRF token (validated against/^[a-z0-9]+$/) and the form ID (validated against/^\d+$/), and returnsfalseif any component is malformed.
Patched generate_user_file_dirpath()
The patch adds this validation logic to the previously unprotected function:
public static function generate_user_file_dirpath( $form_id, $name ) { if ( ! static::_is_valid_path_segment( $name ) ) { throw new \RuntimeException( '[MW WP Form] Invalid file reference requested.' ); } $user_dir = static::generate_user_dirpath( $form_id ); $user_file_dir = path_join( $user_dir, $name ); if ( ! static::_is_within_expected_dir_candidate( $form_id, $user_file_dir ) ) { throw new \RuntimeException( '[MW WP Form] Invalid file reference requested.' ); } return $user_file_dir; }
Patched generate_user_filepath()
The patch replaced the old inline check (wp_basename($normalized_filename) !== $normalized_filename || strstr($normalized_filename, "\0")) with the segment validator up front and the containment check after the path is assembled:
if ( ! static::_is_valid_path_segment( $filename ) ) { throw new \RuntimeException( '[MW WP Form] Invalid file reference requested.' ); } // ... path assembled ... if ( ! static::_is_within_expected_dir_candidate( $form_id, $filepath ) ) { throw new \RuntimeException( '[MW WP Form] Invalid file reference requested.' ); }
generate_user_dirpath() also gained a numeric-only form ID check:
if ( ! preg_match( '/^\d+$/', (string) $form_id ) ) { throw new \RuntimeException( '[MW WP Form] Invalid form ID.' ); }
Caller-Side Error Handling
Both regenerate_upload_file_keys() in class.data.php and _get_attachments() in class.main.php were updated to wrap calls to generate_user_filepath() in try/catch blocks. When the code catches a RuntimeException (a sign of a path traversal attempt), it logs the error, removes the offending upload key from the list, clears its value, and continues processing the remaining legitimate keys. A single malicious entry therefore does not crash the entire form submission.
The commit also includes unit tests in test-directory.php and test-data.php covering absolute paths, nested paths, directory traversal sequences like ../../../wordpress, and Windows-style absolute paths.
Detection Methods
Web Server Access Log Analysis
The most direct detection method targets the attack's entry point, the mwf_upload_files[] POST parameter. Defenders should review web server access logs (Apache, Nginx, or a reverse proxy) for POST requests to any MW WP Form endpoint where the request body includes mwf_upload_files keys containing absolute filesystem paths or path traversal sequences (e.g., ../). Because the vulnerability requires no authentication, any external IP making such requests is suspect. Web Application Firewalls (WAFs) can be configured to inspect POST body parameters for the mwf_upload_files key combined with values that begin with / or contain traversal patterns like ...
PHP Error Log Monitoring (Post-Patch)
If you have already applied the patch (version 5.1.2), the fix itself gives you a built-in detection mechanism. Whenever it detects an invalid path segment, the patched code calls error_log() with the message from a RuntimeException. Exploitation attempts against a patched instance will produce entries in the PHP error log containing the string [MW WP Form] Invalid file reference requested. Multiple occurrences from the same source IP should be treated as high-confidence indicators of targeted attack activity.
File System Integrity Monitoring
The exploit uses PHP's rename(), so the targeted file is moved into the WordPress uploads directory rather than copied. A successful exploitation therefore produces two simultaneous filesystem anomalies: (1) a critical file such as wp-config.php disappears from its expected location, and (2) that same file appears unexpectedly inside the wp-content/uploads/ directory tree. File Integrity Monitoring (FIM) tools such as OSSEC, Wazuh, or Tripwire should be configured to alert on any deletion or modification of wp-config.php and other sensitive WordPress core files. Monitoring the uploads directory for non-media files (e.g., .php, .conf, .ini files) can also catch post-exploitation artifacts.
Behavioral and Host-Based Indicators
A successful exploitation will almost certainly cause an immediate, observable side effect. If wp-config.php is moved, the WordPress site will display Error establishing a database connection because the application can no longer locate its configuration. If this error suddenly appears on a previously working site running MW WP Form, investigate it for this CVE. Uptime monitoring and synthetic health checks on WordPress instances running MW WP Form can act as a fast-response detection layer.
Vulnerability Scanning and Version Detection
Standard vulnerability scanners (Nessus, Qualys, OpenVAS) and WordPress-specific tools like WPScan or Wordfence can identify vulnerable installations by checking the MW WP Form plugin version. Any installation running version 5.1.1 or earlier is affected.
Note on Public Signatures
As of publication, no vendor-agnostic IDS/IPS rules (Snort, Suricata), Sigma rules, or YARA rules explicitly targeting CVE-2026-5436 have been identified in public repositories. For now, the most actionable approaches are the detection strategies above, particularly log monitoring for the mwf_upload_files[] parameter with path-like values, PHP error log alerting, and FIM on critical WordPress files.
Affected Systems and Versions
All versions of the MW WP Form plugin for WordPress up to and including version 5.1.1 are affected. The vulnerability is only exploitable on installations where both of the following conditions are true:
- A file upload field is present on at least one active form.
- The "Saving inquiry data in database" option is enabled for that form.
The fix is available in version 5.1.2 and later.
Vendor Security History
The MW WP Form plugin has a documented pattern of severe file handling vulnerabilities across consecutive releases, all exploitable without authentication:
| Plugin Version Range | Vulnerability Type | CVE |
|---|---|---|
| Versions 5.0.1 and earlier | Unauthenticated Arbitrary File Upload | Related prior CVE |
| Versions 5.1.0 and earlier | Unauthenticated Arbitrary File Move via move_temp_file_to_upload_dir | Related prior CVE |
| Versions 5.1.1 and earlier | Unauthenticated Arbitrary File Move and Read via regenerate_upload_file_keys | CVE-2026-5436 |
These file manipulation flaws keep recurring, and all of them center on insufficient input validation in file system operations. That pattern suggests systemic architectural weaknesses in the plugin's file handling code. Organizations using this plugin should scrutinize future updates closely and consider strict WAF rules for all form submissions as an additional layer of defense.
References
- NVD: CVE-2026-5436
- CVE Record: CVE-2026-5436
- Wordfence Threat Intel: CVE-2026-5436
- Wordfence Blog: 200,000 WordPress Sites Affected
- Wordfence: MW WP Form 5.1.1 Vulnerability Detail
- Wordfence: MW WP Form 5.1.0 Vulnerability Detail
- Wordfence: MW WP Form 5.0.1 Vulnerability Detail
- GitHub Commit f872ab18 (Security Fix)
- GitHub API: Commit f872ab18
- WordPress Plugin Changeset 3501261
- class.data.php (Vulnerable Version)
- class.directory.php (Vulnerable Version)
- GitHub: inc2734/mw-wp-form Repository
- Malware.news Coverage



