Automated Threat Modeling

Ninja Forms File Uploads CVE-2026-0740: Overview of a Critical Unauthenticated Arbitrary File Upload Leading to RCE

CVE-2026-0740 is a CVSS 9.8 unauthenticated arbitrary file upload vulnerability in the Ninja Forms File Uploads WordPress plugin, affecting 50,000 installations. This post covers the patch history, detection methods, and affected version ranges.

CVE Analysis

9 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-06

Ninja Forms File Uploads CVE-2026-0740: Overview of a Critical Unauthenticated Arbitrary File Upload Leading to RCE
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A missing file type check in the Ninja Forms File Uploads plugin for WordPress lets unauthenticated attackers upload PHP webshells and get remote code execution on roughly 50,000 active installations. The flaw is tracked as CVE-2026-0740, with a CVSS score of 9.8. It went through a multi-stage patching process before version 3.3.27 fully resolved it.

The Ninja Forms File Uploads plugin is a commercial add-on for the Ninja Forms form builder, whose core plugin has over 600,000 active installations. It lets WordPress site administrators accept file uploads through forms. The File Uploads extension itself has an estimated 50,000 active installations.

Technical Information

The vulnerability is in the NF_FU_AJAX_Controllers_Uploads class, in the _process() method that moves uploaded files to their final destination on the server.

Root Cause

The plugin's handle_upload() function processes incoming file uploads and hands off to _process(), which calls move_uploaded_file() to save the file to disk. A _validate() function exists and checks the source filename, but the code never checks the destination filename or its extension before the move. The destination filename comes from a user-controlled POST parameter ($new_tmp_name), and the server trusts it without any sanitization or validation.

This is a textbook case of CWE-434 (Unrestricted Upload of File with Dangerous Type), made worse by the fact that the destination parameter also accepts path traversal sequences.

Attack Flow

The exploitation chain works like this:

  1. An unauthenticated attacker sends an HTTP POST request to wp-admin/admin-ajax.php, targeting the Ninja Forms upload AJAX action tied to the NF_FU_AJAX_Controllers_Uploads::handle_upload function.
  2. The attacker sets the destination filename parameter to a name with a .php extension (e.g., shell.php). The attacker can also add path traversal sequences (e.g., ../../../shell.php) to place the file in the document root or another web-accessible directory.
  3. The _process() method receives this parameter, does no validation on the destination filename, and calls move_uploaded_file() to write the attacker's payload to the specified path.
  4. The attacker then sends a standard HTTP GET request to the uploaded PHP file's URL, which executes the webshell or arbitrary PHP code.

The CVSS 3.1 vector describes a network attack with low complexity that needs no privileges and no user interaction. Confidentiality, integrity, and availability impacts are all rated High.

Why the Partial Patches Failed

Versions 3.3.25 and 3.3.26 tried to fix the issue but left exploitable gaps. Version 3.3.25 added uploaded file path sanitization and made file type validation case-insensitive. Version 3.3.26 expanded the extension blacklist to block executable file variants. Bypasses still worked in both versions, because the underlying problem, the lack of validation on the destination filename at the point of use, was not fully fixed until version 3.3.27.

Patch Information

The fix shipped in stages across three plugin releases. Ninja Forms File Uploads version 3.3.27, released on March 16, 2026, completed it.

Version 3.3.25 (January 26, 2026): Partial patch. Added uploaded file path sanitization and made file type validation case-insensitive. Did not fully close the vulnerability.

Version 3.3.26 (February 9, 2026): Still exploitable. Expanded the extension blacklist to block executable file variants, but bypasses remained possible.

Version 3.3.27 (March 16, 2026): Full patch. Closed the final bypass by blocking the destination filename whitelist bypass in file upload.

The patched _process() method runs three security checks on the user-supplied destination filename before it moves any file:

  1. It passes the destination filename through basename(), which strips any directory components and stops path traversal.
  2. It applies WordPress's sanitize_file_name() function to neutralize special characters or encoding tricks.
  3. It extracts the destination filename's extension and checks it against the plugin's extension blacklist. If the extension is blacklisted (e.g., .php, .phtml, .phar), the plugin rejects the upload, deletes the temp file, and returns an error.

This is the defensive block the patch adds to _process():

if ( ! empty( $new_tmp_name ) ) { // Remove any path traversal attempts - use only the basename $new_tmp_name = basename( $new_tmp_name ); // Apply WordPress filename sanitization $new_tmp_name = sanitize_file_name( $new_tmp_name ); // Validate destination extension against blacklist $dest_extension = strtolower( pathinfo( $new_tmp_name, PATHINFO_EXTENSION ) ); if ( self::blacklisted( self::get_extension_blacklist(), $dest_extension ) ) { $this->_errors[] = sprintf( __( 'File extension of %s not allowed', 'ninja-forms-uploads' ), $dest_extension ); unset( $this->_data['files'][ $key ] ); @unlink( $file['tmp_name'] ); continue; } }

The original code validated the uploaded file's name but blindly trusted the attacker-controlled destination parameter. Validation has to happen at the point of use, not only at input, and this fix applies that rule. The patch checks both the source and destination filenames before move_uploaded_file() or file_put_contents() writes anything to disk.

Administrators must update to version 3.3.27 or later. Versions 3.3.25 and 3.3.26 remain exploitable despite their partial fixes.

Detection Methods

CVE-2026-0740 has strong vendor detection coverage, and defenders have several practical ways to spot both exploitation attempts and signs of a compromise.

Wordfence Web Application Firewall (WAF) Rule

The most direct detection comes from Wordfence, the CNA that coordinated disclosure. On January 8, 2026, the same day the flaw was reported, Wordfence deployed a dedicated firewall rule for its Premium, Care, and Response customers. Free-tier Wordfence users received the same rule 30 days later, on February 7, 2026. As of early April 2026, the Wordfence threat intelligence page confirms the rule is actively blocking attacks, and reports that it blocked 3,293 attacks targeting this vulnerability in the past 24 hours. If your WordPress sites run the Wordfence plugin, this rule gives you real-time blocking and alerting with no extra setup.

Alert Logic Network-Based IDS Signatures

Alert Logic (now Fortra) has published a security bulletin for Ninja Forms file upload attacks and confirms that its Network-Based Intrusion Detection System (IDS) now has signatures for this exploit class. When Alert Logic Threat Manager detects matching traffic, it automatically creates an incident in the Alert Logic console. This helps organizations that monitor traffic at the network perimeter instead of relying only on host-based WordPress defenses.

FortiGuard IPS Coverage

Fortinet's FortiGuard Labs maintains an IPS signature titled WordPress.Ninja.Forms.Unauthenticated.Arbitrary.File.Upload, available in both the Regular and Extended IPS databases. The signature entry currently documented in the FortiGuard encyclopedia references older affected versions (2.9.36 to 2.9.42), but its detection logic targets the same attack pattern: malicious file upload requests sent through the Ninja Forms AJAX handler. Organizations running FortiGate devices should confirm their IPS definitions are current and watch for an updated or supplemental FortiGuard signature scoped to CVE-2026-0740 and version range 3.3.26 and below.

Web Server Access Log Analysis

The Wordfence technical writeup lays out the full exploitation mechanics, so defenders can run targeted log analysis even without a commercial WAF. The attack uses HTTP POST requests to wp-admin/admin-ajax.php with the Ninja Forms upload action tied to the NF_FU_AJAX_Controllers_Uploads::handle_upload function. The exploit sets the destination filename parameter to inject a .php extension, and may include path traversal sequences (e.g., ../) to place the malicious file in an accessible directory such as the webroot.

Review web server access logs for POST requests to admin-ajax.php that reference the nf_fu_upload action (or related Ninja Forms upload actions) where the file parameters contain .php extensions or directory traversal characters. These patterns would be unusual in legitimate Ninja Forms use, which makes them strong indicators of exploitation.

Filesystem-Based Post-Exploitation Indicators

A successful exploit leaves forensic artifacts on disk. Look for:

  • Newly created .php files in the WordPress uploads directory (typically wp-content/uploads/) or unexpectedly in the document root
  • Files owned by the web server user that were not created through the normal WordPress media upload workflow
  • Files with obfuscated PHP content or known webshell signatures

File integrity monitoring (FIM) tools, or even a simple comparison against a known-good baseline, can surface these changes. In a SIEM, correlating suspicious admin-ajax.php POST activity in web server logs with later filesystem write events for .php files gives you a high-confidence detection chain.

Version Enumeration

The simplest way to find vulnerable installations ahead of an attack is to check the version. All versions of the Ninja Forms File Uploads plugin up to and including 3.3.26 are vulnerable. Version 3.3.25 is only partially patched. Vulnerability scanners such as WPScan, or a manual look at the plugin's readme.txt or version metadata, can confirm exposure. Wordfence Intelligence and NVD both track this CVE, and you can query their APIs to match it against your assets automatically.

Affected Systems and Versions

Version RangeStatus
All versions up to and including 3.3.24Fully vulnerable
Version 3.3.25Partially patched, still exploitable
Version 3.3.26Partially patched, still exploitable
Version 3.3.27 and laterFully patched

The affected software is the Ninja Forms File Uploads add-on plugin for WordPress, not the core Ninja Forms plugin. Any WordPress site running the File Uploads extension at version 3.3.26 or below is vulnerable. Exploitation needs no authentication and no particular WordPress configuration beyond the plugin being installed and active.

Vendor Security History

Saturday Drive INC, the developer of Ninja Forms, has a track record of fixing security issues across its plugins. Recent security-related updates to the core Ninja Forms plugin include version 3.14.2, which protected block endpoints against unauthorized access, and version 3.14.1, which fixed a cross-site scripting vulnerability. During the CVE-2026-0740 disclosure, the vendor acknowledged the report within four days and worked through several patch iterations. Still, two months passed between initial disclosure and full remediation, which shows how hard file upload validation flaws can be to close completely.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization