| @@ -26,9 +26,8 @@ | ||
| 26 | 26 | class Uploads_Manager extends Base_Object { |
| 27 | 27 | |
| 28 | 28 | const UNFILTERED_FILE_UPLOADS_KEY = 'elementor_unfiltered_files_upload'; |
| 29 | 29 | const INVALID_FILE_CONTENT = 'Invalid Content In File'; |
| 30 | - const ELEMENTOR_UPLOAD_DIR = 'elementor'; | |
| 31 | 30 | |
| 32 | 31 | /** |
| 33 | 32 | * @var File_Type_Base[] |
| 34 | 33 | */ |
| @@ -138,29 +137,11 @@ | ||
| 138 | 137 | if ( is_wp_error( $data ) ) { |
| 139 | 138 | return $data; |
| 140 | 139 | } |
| 141 | 140 | |
| 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 | 141 | $validation_result = $this->validate_file( $data, $allowed_file_extensions ); |
| 157 | 142 | |
| 158 | 143 | 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 | 144 | return $validation_result; |
| 164 | 145 | } |
| 165 | 146 | |
| 166 | 147 | return $data; |
| @@ -272,58 +253,11 @@ | ||
| 272 | 253 | return $data; |
| 273 | 254 | } |
| 274 | 255 | |
| 275 | 256 | /** |
| 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 | 257 | * Remove File Or Directory |
| 323 | 258 | * |
| 324 | 259 | * 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 | 260 | * |
| 327 | 261 | * @since 3.3.0 |
| 328 | 262 | * @access public |
| 329 | 263 | * |
| @@ -329,12 +263,8 @@ | ||
| 329 | 263 | * |
| 330 | 264 | * @param string $path |
| 331 | 265 | */ |
| 332 | 266 | public function remove_file_or_dir( $path ) { |
| 333 | - if ( ! $this->is_path_in_allowed_dir( $path ) ) { | |
| 334 | - return; | |
| 335 | - } | |
| 336 | - | |
| 337 | 267 | if ( is_dir( $path ) ) { |
| 338 | 268 | $this->remove_directory_with_files( $path ); |
| 339 | 269 | } elseif ( is_file( $path ) ) { |
| 340 | 270 | unlink( $path ); |
| @@ -391,9 +321,9 @@ | ||
| 391 | 321 | public function get_temp_dir() { |
| 392 | 322 | if ( ! $this->temp_dir ) { |
| 393 | 323 | $wp_upload_dir = wp_upload_dir(); |
| 394 | 324 | |
| 395 | - $temp_dir = implode( DIRECTORY_SEPARATOR, [ $wp_upload_dir['basedir'], self::ELEMENTOR_UPLOAD_DIR, 'tmp' ] ) . DIRECTORY_SEPARATOR; | |
| 325 | + $temp_dir = implode( DIRECTORY_SEPARATOR, [ $wp_upload_dir['basedir'], 'elementor', 'tmp' ] ) . DIRECTORY_SEPARATOR; | |
| 396 | 326 | |
| 397 | 327 | /** |
| 398 | 328 | * Temp File Path |
| 399 | 329 | * |