PluginProbe
Elementor Website Builder – more than just a page builder / 3.24.4
Elementor Website Builder – more than just a page builder v3.24.4
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
← All changes | core/files/uploads-manager.php +4 -93 4.1.0-dev23.24.4 View file →
@@ -6,11 +6,9 @@
6 6 use Elementor\Core\Files\File_Types\Base as File_Type_Base;
7 7 use Elementor\Core\Files\File_Types\Json;
8 8 use Elementor\Core\Files\File_Types\Svg;
9 9 use Elementor\Core\Files\File_Types\Zip;
10 -use Elementor\Core\Files\Fonts\Google_Font;
11 10 use Elementor\Core\Utils\Exceptions;
12 -use Elementor\Fonts;
13 11 use Elementor\User;
14 12
15 13 if ( ! defined( 'ABSPATH' ) ) {
16 14 exit; // Exit if accessed directly.
@@ -26,9 +24,8 @@
26 24 class Uploads_Manager extends Base_Object {
27 25
28 26 const UNFILTERED_FILE_UPLOADS_KEY = 'elementor_unfiltered_files_upload';
29 27 const INVALID_FILE_CONTENT = 'Invalid Content In File';
30 - const ELEMENTOR_UPLOAD_DIR = 'elementor';
31 28
32 29 /**
33 30 * @var File_Type_Base[]
34 31 */
@@ -75,9 +72,9 @@
75 72 * @since 3.3.0
76 73 * @access public
77 74 *
78 75 * @param string $file_path
79 - * @param array $allowed_file_types
76 + * @param array $allowed_file_types
80 77 * @return array|\WP_Error
81 78 */
82 79 public function extract_and_validate_zip( $file_path, $allowed_file_types = null ) {
83 80 $result = [];
@@ -138,29 +135,11 @@
138 135 if ( is_wp_error( $data ) ) {
139 136 return $data;
140 137 }
141 138
142 - if ( ! isset( $data['fileData'] ) ) {
143 - if ( empty( $data['tmp_name'] ) ) {
144 - return new \WP_Error( 'file_error', esc_html__( 'Invalid temporary file path.', 'elementor' ) );
145 - }
146 -
147 - // Path validation only applies to direct calls (e.g. import_template) where
148 - // tmp_name originates from user input. When is_elementor_upload is true, this
149 - // method is used as a WordPress filter (wp_handle_sideload_prefilter) and
150 - // tmp_name is set by WordPress core.
151 - if ( ! $this->is_elementor_upload && ! $this->is_path_in_allowed_dir( $data['tmp_name'] ) ) {
152 - return new \WP_Error( 'file_error', esc_html__( 'Invalid temporary file path.', 'elementor' ) );
153 - }
154 - }
155 -
156 139 $validation_result = $this->validate_file( $data, $allowed_file_extensions );
157 140
158 141 if ( is_wp_error( $validation_result ) ) {
159 - if ( ! empty( $data['tmp_name'] ) ) {
160 - $this->remove_file_or_dir( dirname( $data['tmp_name'] ) );
161 - }
162 -
163 142 return $validation_result;
164 143 }
165 144
166 145 return $data;
@@ -166,9 +145,9 @@
166 145 return $data;
167 146 }
168 147
169 148 /**
170 - * Is Unfiltered Uploads Enabled
149 + * are Unfiltered Uploads Enabled
171 150 *
172 151 * @since 3.5.0
173 152 * @access public
174 153 *
@@ -174,9 +153,9 @@
174 153 *
175 154 * @return bool
176 155 */
177 156 final public static function are_unfiltered_uploads_enabled() {
178 - $enabled = (bool) get_option( self::UNFILTERED_FILE_UPLOADS_KEY )
157 + $enabled = ! ! get_option( self::UNFILTERED_FILE_UPLOADS_KEY )
179 158 && Svg::file_sanitizer_can_run()
180 159 && User::is_current_user_can_upload_json();
181 160
182 161 /**
@@ -272,58 +251,11 @@
272 251 return $data;
273 252 }
274 253
275 254 /**
276 - * Check if path is within the allowed Elementor uploads directory.
277 - *
278 - * Prevents path traversal and arbitrary directory deletion by ensuring the path
279 - * resolves under wp-content/uploads/elementor/ or under the configured temp dir
280 - * (elementor/files/temp-dir filter), so that cleanup works when temp dir is customized.
281 - *
282 - * @since 3.35.4
283 - * @access private
284 - *
285 - * @param string $path
286 - * @return bool
287 - */
288 - private function is_path_in_allowed_dir( $path ) {
289 - if ( ! is_string( $path ) || '' === $path ) {
290 - return false;
291 - }
292 -
293 - $real_path = realpath( $path );
294 -
295 - if ( false === $real_path ) {
296 - $real_path = realpath( dirname( $path ) );
297 - if ( false === $real_path ) {
298 - return false;
299 - }
300 - }
301 -
302 - $wp_upload_dir = wp_upload_dir();
303 - $elementor_base = realpath( $wp_upload_dir['basedir'] . DIRECTORY_SEPARATOR . self::ELEMENTOR_UPLOAD_DIR );
304 -
305 - if ( false !== $elementor_base ) {
306 - $allowed = $real_path === $elementor_base || 0 === strpos( $real_path, $elementor_base . DIRECTORY_SEPARATOR );
307 - if ( $allowed ) {
308 - return true;
309 - }
310 - }
311 -
312 - $temp_dir = realpath( $this->get_temp_dir() );
313 - if ( false !== $temp_dir ) {
314 - $temp_dir = rtrim( $temp_dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
315 - return 0 === strpos( $real_path, $temp_dir );
316 - }
317 -
318 - return false;
319 - }
320 -
321 - /**
322 255 * Remove File Or Directory
323 256 *
324 257 * Directory is deleted recursively with all of its contents (subdirectories and files).
325 - * Only paths under wp-content/uploads/elementor/ are allowed (security: prevents arbitrary directory deletion).
326 258 *
327 259 * @since 3.3.0
328 260 * @access public
329 261 *
@@ -329,12 +261,8 @@
329 261 *
330 262 * @param string $path
331 263 */
332 264 public function remove_file_or_dir( $path ) {
333 - if ( ! $this->is_path_in_allowed_dir( $path ) ) {
334 - return;
335 - }
336 -
337 265 if ( is_dir( $path ) ) {
338 266 $this->remove_directory_with_files( $path );
339 267 } elseif ( is_file( $path ) ) {
340 268 unlink( $path );
@@ -391,9 +319,9 @@
391 319 public function get_temp_dir() {
392 320 if ( ! $this->temp_dir ) {
393 321 $wp_upload_dir = wp_upload_dir();
394 322
395 - $temp_dir = implode( DIRECTORY_SEPARATOR, [ $wp_upload_dir['basedir'], self::ELEMENTOR_UPLOAD_DIR, 'tmp' ] ) . DIRECTORY_SEPARATOR;
323 + $temp_dir = implode( DIRECTORY_SEPARATOR, [ $wp_upload_dir['basedir'], 'elementor', 'tmp' ] ) . DIRECTORY_SEPARATOR;
396 324
397 325 /**
398 326 * Temp File Path
399 327 *
@@ -443,9 +371,8 @@
443 371 * @param Ajax $ajax
444 372 */
445 373 public function register_ajax_actions( Ajax $ajax ) {
446 374 $ajax->register_ajax_action( 'enable_unfiltered_files_upload', [ $this, 'enable_unfiltered_files_upload' ] );
447 - $ajax->register_ajax_action( 'enqueue_google_fonts', [ $this, 'ajax_enqueue_google_fonts' ] );
448 375 }
449 376
450 377 /**
451 378 * Set Unfiltered Files Upload
@@ -458,24 +385,8 @@
458 385 return;
459 386 }
460 387
461 388 update_option( self::UNFILTERED_FILE_UPLOADS_KEY, 1 );
462 - }
463 -
464 - public function ajax_enqueue_google_fonts( $data ): bool {
465 - if ( empty( $data['font_name'] ) ) {
466 - return false;
467 - }
468 -
469 - $font_type = Fonts::get_font_type( $data['font_name'] );
470 -
471 - if ( Fonts::GOOGLE !== $font_type ) {
472 - return false;
473 - }
474 -
475 - Google_Font::enqueue( $data['font_name'] );
476 -
477 - return true;
478 389 }
479 390
480 391 /**
481 392 * Support Unfiltered File Uploads