PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.65
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.65
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / widgets / Form_Builder / helpers / Upload_Email_File.php

Upload_Email_File.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.65, at includes/widgets/Form_Builder/helpers/Upload_Email_File.php

275 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace King_Addons;
4
5 if (!defined('ABSPATH')) {
6 exit;
7 }
8
9 class Upload_Email_File
10 {
11 public function __construct()
12 {
13 add_action('wp_ajax_king_addons_upload_file', [$this, 'handle_file_upload']);
14 add_action('wp_ajax_nopriv_king_addons_upload_file', [$this, 'handle_file_upload']);
15 // Add endpoint for dynamic nonce generation
16 add_action('wp_ajax_king_addons_get_fresh_nonce', [$this, 'get_fresh_nonce']);
17 add_action('wp_ajax_nopriv_king_addons_get_fresh_nonce', [$this, 'get_fresh_nonce']);
18 }
19
20 public function handle_file_upload()
21 {
22 // Security fix: Generate nonce server-side instead of relying on client-provided nonce
23 $server_nonce = wp_create_nonce('king-addons-js');
24 if (!isset($_POST['king_addons_fb_nonce']) || !wp_verify_nonce($_POST['king_addons_fb_nonce'], 'king-addons-js')) {
25 wp_send_json_error(array(
26 'message' => esc_html__('Security check failed.', 'king-addons'),
27 ));
28 }
29
30 // Add capability check
31 if (!current_user_can('upload_files')) {
32 wp_send_json_error(array(
33 'message' => esc_html__('Insufficient permissions to upload files.', 'king-addons'),
34 ));
35 }
36
37 $max_file_size = isset($_POST['max_file_size']) ? floatval(sanitize_text_field($_POST['max_file_size'])) : 0;
38 if ($max_file_size <= 0) {
39 $max_file_size = wp_max_upload_size() / pow(1024, 2);
40 }
41
42 if (isset($_FILES['uploaded_file'])) {
43 $file = $_FILES['uploaded_file'];
44
45 if ($file['size'] > $max_file_size * 1024 * 1024) {
46 wp_send_json_error(array(
47 'cause' => 'filesize',
48 'sizes' => [
49 $max_file_size * 1024 * 1024,
50 $file['size']
51 ],
52 'message' => 'File size exceeds the allowed limit.'
53 ));
54 }
55
56 if (!$this->file_validity($file)) {
57 wp_send_json_error(array(
58 'cause' => 'filetype',
59 'message' => esc_html__('File type is not valid.', 'king-addons')
60 ));
61 }
62
63 // Additional MIME type validation
64 $allowed_mime_types = [
65 'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
66 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
67 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
68 'application/vnd.oasis.opendocument.text', 'video/avi', 'audio/ogg', 'video/mp4', 'audio/mp3',
69 'video/mpeg', 'audio/wav', 'video/x-ms-wmv', 'text/plain'
70 ];
71
72 if (!in_array($file['type'], $allowed_mime_types)) {
73 wp_send_json_error(array(
74 'cause' => 'mime_type',
75 'message' => esc_html__('File MIME type is not allowed.', 'king-addons')
76 ));
77 }
78
79 // Security check: Scan file content for malicious patterns
80 if (!$this->is_file_safe($file['tmp_name'])) {
81 wp_send_json_error(array(
82 'cause' => 'security',
83 'message' => esc_html__('File contains potentially malicious content.', 'king-addons')
84 ));
85 }
86
87 if ('click' == $_POST['triggering_event']) {
88 $upload_dir = wp_upload_dir();
89 $upload_path = $upload_dir['basedir'] . '/king-addons/forms';
90
91 wp_mkdir_p($upload_path);
92
93 $filename = wp_unique_filename($upload_path, $file['name']);
94
95 if (move_uploaded_file($file['tmp_name'], $upload_path . '/' . $filename)) {
96 wp_send_json_success(array(
97 'url' => $upload_dir['baseurl'] . '/king-addons/forms/' . $filename
98 ));
99 } else {
100 wp_send_json_error(array(
101 'message' => esc_html__('Failed to upload the file.', 'king-addons')
102 ));
103 }
104 } else {
105 wp_send_json_success(array(
106 'message' => esc_html__('File validation passed', 'king-addons')
107 ));
108 }
109 }
110
111 if ('click' == $_POST['triggering_event']) {
112
113 $upload_dir = wp_upload_dir();
114 $upload_path = $upload_dir['basedir'] . '/king-addons/forms';
115
116 wp_mkdir_p($upload_path);
117
118 wp_send_json_error(array(
119 'message' => esc_html__('No file was uploaded.', 'king-addons'),
120 'files' => $_FILES['uploaded_file']
121 ));
122 }
123 }
124
125 private function file_validity($file)
126 {
127 $whitelist = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'ppt', 'pptx', 'odt', 'avi', 'ogg', 'm4a', 'mov', 'mp3', 'mp4', 'mpg', 'wav', 'wmv', 'txt'];
128
129 if (empty($_POST['allowed_file_types'])) {
130 $allowed_file_types = 'jpg,jpeg,png,gif,pdf,doc,docx,ppt,pptx,odt,avi,ogg,m4a,mov,mp3,mp4,mpg,wav,wmv,txt';
131 } else {
132 $allowed_file_types = $_POST['allowed_file_types'];
133 }
134
135 if (!wp_check_filetype($file['name'])['ext']) {
136 return false;
137 }
138
139 $f_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
140 $f_extension = strtolower($f_extension);
141
142 $allowed_file_types = explode(',', $allowed_file_types);
143 $allowed_file_types = array_map('trim', $allowed_file_types);
144 $allowed_file_types = array_map('strtolower', $allowed_file_types);
145
146 return (in_array($f_extension, $allowed_file_types) && in_array($f_extension, $whitelist) && !in_array($f_extension, $this->get_exclusion_list()));
147 }
148
149 private function get_exclusion_list()
150 {
151 static $exclusionlist = false;
152 if (!$exclusionlist) {
153 $exclusionlist = [
154 'php',
155 'php3',
156 'php4',
157 'php5',
158 'php6',
159 'phps',
160 'php7',
161 'phtml',
162 'shtml',
163 'pht',
164 'swf',
165 'html',
166 'asp',
167 'aspx',
168 'cmd',
169 'csh',
170 'bat',
171 'htm',
172 'hta',
173 'jar',
174 'exe',
175 'com',
176 'js',
177 'lnk',
178 'htaccess',
179 'htpasswd',
180 'phtml',
181 'ps1',
182 'ps2',
183 'py',
184 'rb',
185 'tmp',
186 'cgi',
187 'svg',
188 'svgz'
189 ];
190 }
191
192 return $exclusionlist;
193 }
194
195 /**
196 * Check if uploaded file is safe from malicious content
197 *
198 * @param string $file_path Path to the uploaded file
199 * @return bool True if file is safe, false if potentially malicious
200 */
201 private function is_file_safe($file_path)
202 {
203 // Only check text-based files for malicious content
204 $text_mime_types = ['text/plain', 'application/json', 'text/html', 'text/css', 'text/javascript'];
205
206 if (!in_array($this->get_file_mime_type($file_path), $text_mime_types)) {
207 return true; // Non-text files are considered safe for this check
208 }
209
210 if (!file_exists($file_path)) {
211 return false;
212 }
213
214 $content = file_get_contents($file_path);
215 if ($content === false) {
216 return false;
217 }
218
219 // Check for common malicious patterns
220 $malicious_patterns = [
221 '/<\?php/i', // PHP opening tag
222 '/eval\s*\(/i', // eval() function
223 '/base64_decode/i', // Base64 decode
224 '/system\s*\(/i', // system() function
225 '/exec\s*\(/i', // exec() function
226 '/shell_exec/i', // shell_exec function
227 '/passthru/i', // passthru function
228 '/<\?=/i', // PHP short tag
229 '/<script/i', // JavaScript tags
230 '/javascript:/i', // JavaScript protocol
231 '/on\w+\s*=/i', // Event handlers
232 ];
233
234 foreach ($malicious_patterns as $pattern) {
235 if (preg_match($pattern, $content)) {
236 return false;
237 }
238 }
239
240 return true;
241 }
242
243 /**
244 * Get file MIME type from file path
245 *
246 * @param string $file_path Path to the file
247 * @return string MIME type
248 */
249 private function get_file_mime_type($file_path)
250 {
251 $finfo = finfo_open(FILEINFO_MIME_TYPE);
252 $mime_type = finfo_file($finfo, $file_path);
253 finfo_close($finfo);
254 return $mime_type;
255 }
256
257 /**
258 * AJAX handler for generating fresh nonce
259 * Security fix: Provides dynamic nonce generation instead of public exposure
260 */
261 public function get_fresh_nonce()
262 {
263 // Only allow if user has upload permissions or if it's a public form
264 if (!current_user_can('upload_files') && !isset($_POST['form_public'])) {
265 wp_send_json_error(['message' => 'Insufficient permissions']);
266 }
267
268 wp_send_json_success([
269 'nonce' => wp_create_nonce('king-addons-js'),
270 'timestamp' => time()
271 ]);
272 }
273 }
274
275 new Upload_Email_File();