[wp-trac] [WordPress Trac] #38946: WP_Upgrader: Protection against deleting files in destination directory

WordPress Trac noreply at wordpress.org
Sat Nov 26 09:12:53 UTC 2016


#38946: WP_Upgrader: Protection against deleting files in destination directory
-----------------------------+-----------------------------
 Reporter:  shivapoudel      |      Owner:
     Type:  enhancement      |     Status:  new
 Priority:  normal           |  Milestone:  Awaiting Review
Component:  Upgrade/Install  |    Version:
 Severity:  normal           |   Keywords:
  Focuses:                   |
-----------------------------+-----------------------------
 While creating a plugin I have to upload zip file and extract it in the
 custom destination directory with its inside main folder name just like
 how Theme_Upgrader and Plugin_Upgrader does.

 While extending the class `WP_Upgrader` and using method `install()` like
 this:

 {{{#!php
 <?php
 /**
  * Install a demo package.
  *
  * @since 2.8.0
  * @since 3.7.0 The `$args` parameter was added, making clearing the
 update cache optional.
  * @access public
  *
  * @param string $package The full local path or URI of the package.
  * @param array  $args {
  *     Optional. Other arguments for installing a demo package. Default
 empty array.
  *
  *     @type bool $clear_update_cache Whether to clear the updates cache
 if successful.
  *                                    Default true.
  * }
  *
  * @return bool|WP_Error True if the install was successful, false or a
 WP_Error object otherwise.
  */
 public function install( $package, $args = array() ) {

         $defaults = array(
                 'clear_update_cache' => true,
         );
         $parsed_args = wp_parse_args( $args, $defaults );

         $this->init();
         $this->install_strings();

         add_filter( 'upgrader_source_selection', array( $this,
 'check_package' ) );

         $this->run( array(
                 'package' => $package,
                 'destination' => WP_CONTENT_DIR . '/uploads/demo-packs',
                 'clear_destination' => false, // Do not overwrite files.
                 'protect_destination' => true, // Let me utilize this args
 in `install_package()` to fix this error, happy :)
                 'clear_working' => true,
                 'hook_extra' => array(
                         'type' => 'demo',
                         'action' => 'install',
                 )
         ) );

         remove_filter( 'upgrader_source_selection', array( $this,
 'check_package' ) );

         if ( ! $this->result || is_wp_error( $this->result ) ) {
                 return $this->result;
         }

         return true;
 }
 }}}

 Now always the zip file content are extracted into that destination
 directory but I want to index just like this where `{uploaded-zip}` is the
 zip file inside folder name:

 `WP_CONTENT_DIR . '/uploads/demo-packs/{uploaded-zip}'`

 And finally the detected issue is that the destination directory are no
 more protected just like theme and plugins directories does :)

 {{{#!php
 <?php
 /*
  * Protection against deleting files in any important base directories.
  * Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
  * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
  * to copy the directory into the directory, whilst they pass the source
  * as the actual files to copy.
  */
 $protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR,
 WP_CONTENT_DIR . '/themes' );

 if ( is_array( $wp_theme_directories ) ) {
         $protected_directories = array_merge( $protected_directories,
 $wp_theme_directories );
 }

 if ( in_array( $destination, $protected_directories ) ) {
         $remote_destination = trailingslashit( $remote_destination ) .
 trailingslashit( basename( $source ) );
         $destination = trailingslashit( $destination ) . trailingslashit(
 basename( $source ) );
 }
 }}}



 And this is where the magic begins by adding `protect_destination` args
 and fixing it:

 {{{#!php
 <?php
 if ( in_array( $destination, $protected_directories ) ||
 $args['protect_destination'] ) {
         $remote_destination = trailingslashit( $remote_destination ) .
 trailingslashit( basename( $source ) );
         $destination = trailingslashit( $destination ) . trailingslashit(
 basename( $source ) );
 }
 }}}

--
Ticket URL: <https://core.trac.wordpress.org/ticket/38946>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list