This security advisory is written about a critical Forminator vulnerability initially disclosed by MEHMET KELEPÇE. Patchstack users have received a vPatch to protect their site against this vulnerability.
This blog post is about the Forminator plugin vulnerability. If you're a Forminator user, please update the plugin to at least version 1.25.0.
✌️ Our users are protected from this vulnerability. Are yours?
Automatically mitigate vulnerabilities in real-time without changing code.
See pricingIdentify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsAbout the Forminator Plugin
The plugin Forminator (versions 1.24.6 and below, free version), which has over 400,000 active installations is known as the more popular custom form plugin in WordPress. This plugin is developed by WPMUDEV.

It's claimed that the Forminator’s drag and drop visual builder makes it easy to setup and add forms to our WordPress website. Collect information, make our content interactive and generate more conversions with Forminator.
The security vulnerability
This plugin suffers from an unauthenticated arbitrary file upload vulnerability. This vulnerability allows any unauthenticated user to upload arbitrary files, including PHP files, that could lead to remote code execution. The described vulnerability was fixed in version 1.25.0 and assigned CVE-2023-4596.
We initially discovered and reported the vulnerability to the vendor (WPMUDEV) on 16 August without any clue that the vulnerability was already publicly disclosed by MEHMET KELEPÇE. The vendor then informed us the vulnerability is known to them and already patched it first on the premium version of the plugin. The vendor then published the patch on the free version of the plugin on the same day (August 16th, 2023). We planned to delay the disclosure of the vulnerability, but it turns out that the vulnerability already publicly disclosed.
Unauthenticated Arbitrary File Upload
The underlying vulnerable code exist in the upload_post_image
function:
public function upload_post_image( $field, $field_name ) {
$post_image = self::get_property( 'post_image', $field, '' );
if ( empty( $post_image ) ) {
return true;
}
if ( ! empty( $_FILES[ $field_name ]['name'] ) ) {
$file_name = sanitize_file_name( $_FILES[ $field_name ]['name'] );
// TODO: refactor upload to use WP filesystem api.
$file_data = file_get_contents( $_FILES[ $field_name ]['tmp_name'] );
$upload_dir = wp_upload_dir(); // Set upload folder.
$unique_file_name = wp_unique_filename( $upload_dir['path'], $file_name );
$filename = basename( $unique_file_name ); // Create base file name.
if ( wp_mkdir_p( $upload_dir['path'] ) ) {
$file = $upload_dir['path'] . '/' . $filename;
} else {
$file = $upload_dir['basedir'] . '/' . $filename;
}
// Create the file on the server.
file_put_contents( $file, $file_data );
// Check image file type.
$wp_filetype = wp_check_filetype( $filename, null );
$image_exts = apply_filters( 'forminator_field_postdata_image_file_types', $this->image_extensions );
-------------------------- CUTTED HERE --------------------------
The function is used to handle the upload process of post image. This function can be reached if the site has a Forminator form with the "Create Post" template that allows unauthenticated user to create a post.

Notice that there is no check on the uploaded filename or extension and the file is directly uploaded using the file_put_contents
function. The interesting part is the check on the filetype using the wp_check_filetype
function is only performed after the file has already been uploaded.
The patch
The patch is as simple as moving the file_put_contents
function after the check has been applied. The patch can be seen below:

Conclusion
Always check every process of $_FILES
parameter in the plugin or theme code. Make sure to apply a check on the filename and extension before uploading the file. One of the WordPress built-in functions to check the filetype is wp_check_filetype
.
Timeline
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn more