PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.83
51.1.84 51.1.85 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 All 39 releases
← All changes | includes/widgets/Form_Builder/helpers/Upload_Email_File.php +287 -0 51.1.251.1.83 View file →
@@ -1,0 +1,287 @@
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 a fresh form nonce.
259 + *
260 + * This nonce is a CSRF token for Form Builder AJAX. It is not authorization
261 + * to read or change a submission: payment reuse requires the per-submission
262 + * access secret issued when that submission was created.
263 + *
264 + * Requires a published page that actually contains the Form Builder widget.
265 + * A bare form_public flag is not accepted.
266 + *
267 + * @return void
268 + */
269 + public function get_fresh_nonce()
270 + {
271 + $page_id = absint($_POST['page_id'] ?? 0);
272 +
273 + if (!Form_Builder_Security::page_has_form_builder($page_id)) {
274 + wp_send_json_error([
275 + 'message' => esc_html__('Insufficient permissions.', 'king-addons'),
276 + ]);
277 + }
278 +
279 + wp_send_json_success([
280 + 'nonce' => wp_create_nonce('king-addons-js'),
281 + 'timestamp' => time(),
282 + ]);
283 + }
284 +
285 +}
286 +
287 +new Upload_Email_File();