SECURITY ADVISORY / 01

CVE-2025-6463 Exploit & Vulnerability Analysis

Complete CVE-2025-6463 security advisory with proof of concept (PoC), exploit details, and patch analysis for forminator.

forminator products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker can craft a form submission that embeds an arbitrary file path (e.g., /var/www/html/wp-config.php) in the file metadata. When a site administrator or automated process deletes the form entry, Forminator will delete that file without validating that it resides within the upload directory or that the path has not been manipulated via traversal sequences.

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target.wordpress.local
Content-Type: application/x-www-form-urlencoded

action=forminator_submit_form&form_id=1&forminator-1-name=Test&forminator-1-upload=../../wp-config.php

The attacker observes a 200 response indicating successful form submission. When an admin later deletes that entry—either manually or via plugin-configured auto-deletion—wp_delete_file() executes on the path specified in the hidden metadata, removing /var/www/html/wp-config.php from disk.

What the Patch Did

Before

foreach ( $entry_model->meta_data as $meta_data ) {
    $meta_value = $meta_data['value'];
    if ( is_array( $meta_value ) && isset( $meta_value['file'] ) ) {
        $file_path = is_array( $meta_value['file']['file_path'] ) ? $meta_value['file']['file_path'] : array( $meta_value['file']['file_path'] );
        if ( ! empty( $file_path ) ) {
            foreach ( $file_path as $key => $path ) {
                if ( ! empty( $path ) && file_exists( $path ) ) {
                    wp_delete_file( $path );
                }
            }
        }
    }
}

After

$upload_root = wp_upload_dir();
if ( empty( $upload_root['basedir'] ) ) {
    return;
}
$upload_root = $upload_root['basedir'];
foreach ( $entry_model->meta_data as $slug => $meta_data ) {
    $meta_value = $meta_data['value'];
    $field_type = Forminator_Core::get_field_type( $slug );
    if ( in_array( $field_type, array( 'upload', 'signature' ), true )
            && is_array( $meta_value ) && isset( $meta_value['file'] ) ) {
        $file_path = is_array( $meta_value['file']['file_path'] ) ? $meta_value['file']['file_path'] : array( $meta_value['file']['file_path'] );
        if ( ! empty( $file_path ) ) {
            foreach ( $file_path as $key => $path ) {
                $path = realpath( $path );
                if ( ! $path || ! file_exists( $path ) ) {
                    continue;
                }

                $basename  = wp_basename( $path );
                $sanitized = sanitize_file_name( $basename );
                if ( $basename !== $sanitized ) {
                    continue;
                }

                $normalized_upload_root = wp_normalize_path( $upload_root );
                $normalized_path        = wp_normalize_path( $path );
                if ( ! empty( $normalized_upload_root ) && 0 !== strpos( $normalized_path, $normalized_upload_root ) ) {
                    continue;
                }

                wp_delete_file( $path );
            }
        }
    }
}

The patch adds five security controls. First, it retrieves the canonical upload directory using wp_upload_dir()['basedir'] and normalizes it via wp_normalize_path(). Second, it calls realpath() on every path candidate, collapsing symbolic links and traversal sequences (., ..) to their canonical form. Third, it validates the filename basename with sanitize_file_name(), rejecting entries that contain path separators or other suspicious characters. Fourth, it enforces that the normalized path begins with the normalized upload root using strpos(), ensuring the file cannot exist outside the permitted directory. Finally, the patch restricts the deletion operation to fields explicitly marked as upload or signature types, preventing metadata injection attacks on unexpected field categories.

Root Cause

CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The vulnerability lives in the entry_delete_upload_files() function in library/model/class-form-entry-model.php. During form submission, user-supplied file paths are stored in the entry's meta_data array without validation. An attacker can inject a path like ../../wp-config.php or /etc/passwd into the file_path key. When the entry is later deleted—a process triggered by administrator action or automated expiry logic—the code passes this untrusted path directly to file_exists() and wp_delete_file(). Neither function performs canonicalization or directory confinement, so the operating system resolves the traversal sequences and deletes whatever file the attacker specified.

Why It Works

The load-bearing line is:

$path = realpath( $path );

This function resolves symbolic links, collapses . and .. sequences, and returns a canonical absolute path. If you remove it, an attacker's submission of ../../../wp-config.php will reach the subsequent checks as a string containing literal ../ sequences. The strpos() check against $normalized_upload_root will then fail—not because the path is outside the directory, but because the literal string ../../wp-config.php does not start with /var/www/html/wp-content/uploads. However, if the operating system later resolves it during the wp_delete_file() call, the file will still be deleted.

The engineer added the basename sanitization (sanitize_file_name()) and field-type gating (in_array( $field_type, ... )) as defence-in-depth: they reduce the attack surface by rejecting payloads with suspicious characters and preventing metadata injection into non-file fields. The wp_normalize_path() call is critical because Windows uses backslashes as path separators, and comparing raw strings without normalization could produce false negatives. Together, these controls enforce that only files within the upload directory, with clean basenames, belonging to legitimate upload fields, are eligible for deletion.

Hardening Checklist

  • Use realpath() before any filesystem operation on user-supplied paths. It neutralizes traversal sequences and symlink attacks in a single call; never rely on string-based validation alone.
  • Confine file operations to a whitelist directory using wp_upload_dir() and strpos() prefix matching. All file deletions, reads, and writes should be validated against the canonical upload path.
  • Validate field type at the metadata layer, not the request layer. Use Forminator_Core::get_field_type() or equivalent before processing any file metadata, preventing injection into unintended fields.
  • Sanitize basenames with sanitize_file_name() and reject any path that contains directory separators. This stops encoded or null-byte payloads from bypassing string checks.
  • Normalize paths using wp_normalize_path() before any comparison operation. It abstracts away OS-specific path syntax and prevents bypasses on Windows systems using backslash separators.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2025-6463

Frequently asked questions about CVE-2025-6463

What is CVE-2025-6463?

CVE-2025-6463 is a security vulnerability identified in forminator. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2025-6463?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2025-6463. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2025-6463 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting forminator. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2025-6463?

CVE-2025-6463 affects forminator. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2025-6463?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for forminator.

What is the CVSS score for CVE-2025-6463?

The severity rating and CVSS scoring for CVE-2025-6463 affecting forminator is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.