Append unique hash to filename for added security

This commit is contained in:
vedanshujain 2020-01-15 17:44:43 +05:30
parent 44677bbab7
commit 56176e0479
2 changed files with 106 additions and 0 deletions

View File

@ -54,6 +54,7 @@ class WC_Admin_Post_Types {
// Uploads.
add_filter( 'upload_dir', array( $this, 'upload_dir' ) );
add_filter( 'wp_unique_filename', array( $this, 'wc_unique_filename' ), 10, 3 );
add_action( 'media_upload_downloadable_product', array( $this, 'media_upload_downloadable_product' ) );
// Hide template for CPT archive.
@ -818,6 +819,61 @@ class WC_Admin_Post_Types {
return $pathdata;
}
/**
* Change filename for WooCommerce uploads and prepend unique chars for security.
*
* @param string $full_filename Original filename.
* @param string $ext Extension of file.
* @param string $dir Directory path.
*
* @return string New filename with unique hash.
* @since 3.10.0
*/
public function wc_unique_filename( $full_filename, $ext, $dir ) {
if ( ! isset( $_POST['type'] ) || ! 'downloadable_product' === $_POST['type'] ) { // WPCS: CSRF ok, input var ok.
return $full_filename;
}
if ( ! strpos( $dir, 'woocommerce_uploads' ) ) {
return $full_filename;
}
return $this->unique_filename( $full_filename, $ext );
}
/**
* Change filename to append random text.
*
* @param string $full_filename Original filename with extension.
* @param string $ext Extension.
*
* @return string Modified filename.
*/
public function unique_filename( $full_filename, $ext ) {
$ideal_random_char_length = 32;
$max_filename_length = 255; // Max file name length for most file systems.
$length_to_prepend = min( $ideal_random_char_length, $max_filename_length - strlen( $full_filename ) - 1 );
if ( 1 > $length_to_prepend ) {
return $full_filename;
}
$suffix = strtolower( wp_generate_password( $length_to_prepend, false, false ) );
$filename = $full_filename;
if ( strlen( $ext ) > 0 ) {
$filename = substr( $filename, 0, strlen( $filename ) - strlen( $ext ) );
}
$full_filename = str_replace(
$filename,
"$filename-$suffix",
$full_filename
);
return $full_filename;
}
/**
* Run a filter when uploading a downloadable product.
*/

View File

@ -0,0 +1,50 @@
<?php
/**
* Tests for WC_Test_Admin_Post_Types class.
*
* @package WooCommerce\Tests\Util
*/
/**
* WooCommerce Post Type class.
*/
class WC_Test_Admin_Post_Types extends WC_Unit_Test_Case {
/**
* Instance of WC_Admin_Post_Types.
*
* @var \WC_Admin_Post_Types
*/
protected $wc_cpt;
/**
* Setup. Create a instance to use throughout.
*/
public function setUp() {
parent::setUp();
$this->wc_cpt = new WC_Admin_Post_Types();
}
/**
* Check if filename is extended and extension is preserved.
*/
public function test_unique_filename() {
$full_filename = 'dummy_filename.csv';
$ext = '.csv';
$unique_filename = $this->wc_cpt->unique_filename( $full_filename, $ext );
$this->assertEquals( strlen( $full_filename ) + 32 + 1, strlen( $unique_filename ) );
$this->assertEquals( $ext, substr( $unique_filename, -4 ) );
}
/**
* Check if filename is extended properly when its very long.
*/
public function test_unique_filename_for_large_name() {
$full_filename = str_repeat( 'w', 250 ) . '.csv';
$ext = '.csv';
$unique_filename = $this->wc_cpt->unique_filename( $full_filename, $ext );
$this->assertEquals( 254, strlen( $unique_filename ) );
$this->assertEquals( $ext, substr( $unique_filename, - 4 ) );
}
}