Ninja Forms File Upload CVE-2026-0740 (CVSS 9.8) — 50,000 WordPress Sites Under Active Webshell Attack
Introduction
Wordfence is reporting 3,600+ exploitation attempts in a single 24-hour window against CVE-2026-0740, an unauthenticated arbitrary file upload flaw in the Ninja Forms File Upload premium add-on for WordPress. The bug carries a CVSS 9.8, affects roughly 50,000 active WordPress installations, and lets an attacker drop a PHP webshell directly into the webroot with one HTTP POST. The kicker: the vendor's first patch in February 2026 was incomplete — only version 3.3.27 (released March 19) actually closes the bug. Sites that updated in February and stopped there are still being owned right now. A separate critical (CVE-2026-3844, CVSS 9.8) in the Breeze Cache plugin is being weaponized in parallel campaigns.
What Happened
CVE-2026-0740 lives in NF_FU_AJAX_Controllers_Uploads::handle_upload. The function validates the source filename (the name of the file the attacker is uploading) but never validates the destination filename used in the move() operation. An attacker manipulates the destination parameter to write a PHP file into a webroot directory:
- No authentication required (
AV:N/AC:L/PR:N/UI:N) - Arbitrary
.php/.phtmlextension accepted - Path traversal possible because filename is not sanitized — files can be moved to the webroot
- Once the file is written, the attacker requests it directly to execute arbitrary PHP
Researcher Sélim Lanouar (whattheslime) reported the bug to Wordfence on January 8, 2026 and earned a $2,145 bounty. Wordfence disclosed full details to the vendor the same day and pushed firewall mitigations to its customers as a stopgap.
Saji Software (the Ninja Forms File Upload vendor) released:
- 3.3.25 on February 10, 2026 — partial fix; "addressed some but not all bypass vectors" per CyCognito
- 3.3.26 — still vulnerable
- 3.3.27 on March 19, 2026 — full fix
The Ninja Forms File Upload extension is a paid add-on distributed through ninjaforms.com, not through the WordPress.org plugin repository. WordPress's auto-update mechanism does not always pull the latest version from third-party channels. Site owners need to verify the installed version manually.
In parallel, attackers are exploiting CVE-2026-3844 in the Breeze Cache plugin (also CVSS 9.8, also unauthenticated arbitrary file upload). The Hacker News reports both campaigns are running simultaneously and result in arbitrary code execution and complete site takeover.
Public PoCs exist. Wordfence and BleepingComputer both confirm in-the-wild exploitation. The webshell observed in the wild is a randomly-named 8-character .php file dropped into the WordPress uploads folder or directly to the webroot.
Why It Matters
WordPress runs roughly 43% of the public web, and Ninja Forms is one of the most-installed contact-form plugins on the planet (3M+ installs of the core plugin; ~50K of the paid File Upload add-on). Compromised WordPress sites become part of every kind of downstream operation: SEO-poisoning campaigns, credit-card skimmers, phishing-page hosting, malvertising redirectors, and increasingly cryptominers and proxy networks. A single webshell on a WooCommerce site puts every payment record and customer credential at risk.
The 24-hour spike in exploitation that Wordfence reported is consistent with the pattern we've seen for every recent critical WordPress flaw: PoC drops → mass scanning starts within hours → automated webshell drops within days. With 50,000 vulnerable sites and a working public PoC, the math is brutal — many thousands have already been compromised but won't notice for weeks.
Who Is Affected
- WordPress sites running Ninja Forms File Upload ≤ 3.3.26 (paid add-on; check ninjaforms.com, not WP repository)
- WordPress sites running Breeze Cache with CVE-2026-3844 unpatched (the broader plugin family from Cloudways/Breeze)
- Any WordPress site that updated to 3.3.25 in February and never went past it
- WooCommerce, membership, and form-driven sites where the file-upload extension is exposed publicly
- Hosts using shared infrastructure where one compromised site can pivot to others on the same filesystem
How to Protect Yourself
Step 1: Verify your installed version. WordPress dashboard → Plugins → Ninja Forms File Upload. Anything below 3.3.27 is vulnerable.
# WP-CLI version check (run from WordPress root)
wp plugin get ninja-forms-uploads --field=version
# or for self-hosted plugin
wp plugin list --status=active | grep -i ninja
If you don't have the plugin: ensure the directory wp-content/plugins/ninja-forms-uploads/ (or similar) doesn't exist as a leftover from an earlier install.
Step 2: Update to 3.3.27 from the vendor. The plugin is distributed through ninjaforms.com — log in, download the latest ZIP, upload via WordPress's plugin uploader, or install via WP-CLI:
cd /tmp
wget https://your-ninjaforms-account-download-url/ninja-forms-uploads-3.3.27.zip
wp plugin install ninja-forms-uploads-3.3.27.zip --force --activate
wp plugin get ninja-forms-uploads --field=version # confirm 3.3.27
For Breeze Cache (CVE-2026-3844), update to the patched release per the vendor advisory — typically via:
wp plugin update breeze
Step 3: Hunt for compromise — every site that ran ≤ 3.3.26 in the past 90 days needs to be checked. Look for unexpected PHP files:
# Find recently modified PHP files in WordPress directories
find /var/www/html -type f -name "*.php" -mtime -90 \
-not -path "*/wp-includes/*" -not -path "*/wp-admin/*" \
-exec ls -la {} \; | sort -k6,7
# Specifically the typical drop locations
find /var/www/html/wp-content/uploads -type f -name "*.php" -ls
find /var/www/html/wp-content/plugins/ninja-forms-uploads/tmp -type f -ls 2>/dev/null
# 8-character random filenames are a known IOC
find /var/www/html -type f -name "????????.php" -ls
Inspect any PHP file outside wp-includes/, wp-admin/, or known plugin/theme paths. Webshells commonly contain eval(, base64_decode(, assert(, or system( calls early in the file:
grep -rE "eval\(|base64_decode\(|assert\(|preg_replace.*[/]e|system\(|exec\(" \
/var/www/html/wp-content/uploads/ /var/www/html/ \
--include="*.php" --include="*.phtml" 2>/dev/null
Step 4: Block PHP execution in upload directories (this should be permanent, not temporary). For Apache, add to wp-content/uploads/.htaccess:
<FilesMatch "\.(?i:php|phtml|phar|phps)$">
Require all denied
</FilesMatch>
For Nginx, in your server block:
location ^~ /wp-content/uploads/ {
location ~ \.(php|phtml|phar|phps)$ {
deny all;
return 403;
}
}
This single control would have neutralized this entire CVE class in your environment.
Step 5: Add WAF rules. If you run Wordfence Premium, the firewall rule was deployed January 8, 2026. Free Wordfence users got it 30 days later. Confirm under Wordfence → Firewall → Status that real-time threat intel is current.
If you use Cloudflare, ModSecurity, or AWS WAF, deploy a temporary rule blocking POST requests to Ninja Forms upload endpoints with Content-Type: multipart/form-data containing .php extensions:
SecRule REQUEST_URI "@contains /wp-admin/admin-ajax.php" \
"id:2026074001,phase:2,deny,status:403,msg:'CVE-2026-0740 attempt',\
chain"
SecRule ARGS:action "@beginsWith nf_fu" "chain"
SecRule REQUEST_BODY "@rx \.(php|phtml|phar)" "t:lowercase"
Step 6: Check downstream impact. If you find a webshell, assume the entire site is compromised:
- Pull a forensic image before cleanup
- Rotate all WordPress admin credentials and database passwords
- Force-reset all WP user passwords (
wp user reset-password --all) - Rotate any API keys stored in
wp-config.phpor in plugin configs (Stripe, Mailchimp, etc.) - Reinstall WordPress core, themes, and plugins from scratch — don't just delete the webshell
- Audit
wp_optionsfor malicious entries (active_plugins,siteurl, custom hooks)
Step 7: Subscribe to vulnerability intel. Wordfence publishes the firehose at wordfence.com/threat-intel, Patchstack at patchstack.com/database, and CVE feeds via NVD. Pipe one of them into your tracker so a CVSS 9.x WordPress flaw doesn't sit untriaged for a week.
Source
- BleepingComputer — Hackers exploit critical flaw in Ninja Forms WordPress plugin
- The Hacker News — LMDeploy CVE-2026-33626 (sidebar coverage of CVE-2026-0740 and CVE-2026-3844)
- Truesec — CVE-2026-0740 Critical Vulnerability in Ninja Forms WordPress Plugin
- eBuilder Security — Ninja Forms File Upload Flaw Lets Attackers Hijack 50,000 WordPress Sites
- SentinelOne — CVE-2026-0740 Vulnerability Database Entry
- NVD — CVE-2026-0740
- Wordfence Threat Intelligence