From ccbbea1eaa8a0dd26aa05a0d860fda550f7dd7a8 Mon Sep 17 00:00:00 2001 From: Adam Jackett Date: Sun, 21 Aug 2011 16:19:11 -0400 Subject: Fixed issue #26. Added max_filename_increment as a config setting. --- system/libraries/Upload.php | 54 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 3177424c4..8f324de79 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -30,6 +30,7 @@ class CI_Upload { public $max_width = 0; public $max_height = 0; public $max_filename = 0; + public $max_filename_increment = 100; public $allowed_types = ""; public $file_temp = ""; public $file_name = ""; @@ -80,31 +81,32 @@ class CI_Upload { public function initialize($config = array()) { $defaults = array( - 'max_size' => 0, - 'max_width' => 0, - 'max_height' => 0, - 'max_filename' => 0, - 'allowed_types' => "", - 'file_temp' => "", - 'file_name' => "", - 'orig_name' => "", - 'file_type' => "", - 'file_size' => "", - 'file_ext' => "", - 'upload_path' => "", - 'overwrite' => FALSE, - 'encrypt_name' => FALSE, - 'is_image' => FALSE, - 'image_width' => '', - 'image_height' => '', - 'image_type' => '', - 'image_size_str' => '', - 'error_msg' => array(), - 'mimes' => array(), - 'remove_spaces' => TRUE, - 'xss_clean' => FALSE, - 'temp_prefix' => "temp_file_", - 'client_name' => '' + 'max_size' => 0, + 'max_width' => 0, + 'max_height' => 0, + 'max_filename' => 0, + 'max_filename_increment' => 100, + 'allowed_types' => "", + 'file_temp' => "", + 'file_name' => "", + 'orig_name' => "", + 'file_type' => "", + 'file_size' => "", + 'file_ext' => "", + 'upload_path' => "", + 'overwrite' => FALSE, + 'encrypt_name' => FALSE, + 'is_image' => FALSE, + 'image_width' => '', + 'image_height' => '', + 'image_type' => '', + 'image_size_str' => '', + 'error_msg' => array(), + 'mimes' => array(), + 'remove_spaces' => TRUE, + 'xss_clean' => FALSE, + 'temp_prefix' => "temp_file_", + 'client_name' => '' ); @@ -402,7 +404,7 @@ class CI_Upload { $filename = str_replace($this->file_ext, '', $filename); $new_filename = ''; - for ($i = 1; $i < 100; $i++) + for ($i = 1; $i < $this->max_filename_increment; $i++) { if ( ! file_exists($path.$filename.$i.$this->file_ext)) { -- cgit v1.2.3-24-g4f1b From 3a3c947790d3d072e14de2b5d21ae43743947ce8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 24 Sep 2011 14:25:33 +0300 Subject: Added _file_mime_type() method to system/libraries/Upload.php in order to fix a possible MIME-type injection (issue #60) --- system/libraries/Upload.php | 68 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 8f324de79..fcfd89915 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -198,7 +198,8 @@ class CI_Upload { // Set the uploaded data as class variables $this->file_temp = $_FILES[$field]['tmp_name']; $this->file_size = $_FILES[$field]['size']; - $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']); + $this->_file_mime_type($_FILES[$field]); + $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $this->file_type); $this->file_type = strtolower(trim(stripslashes($this->file_type), '"')); $this->file_name = $this->_prep_filename($_FILES[$field]['name']); $this->file_ext = $this->get_extension($this->file_name); @@ -1008,8 +1009,71 @@ class CI_Upload { // -------------------------------------------------------------------- + /** + * File MIME type + * + * Detects the (actual) MIME type of the uploaded file, if possible. + * The input array is expected to be $_FILES[$field] + * + * @param array + * @return void + */ + protected function _file_mime_type($file) + { + $file_type = ''; + + // Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag) + if ( (float) substr(phpversion(), 0, 3) >= 5.3 && function_exists('finfo_file')) + { + $finfo = new finfo(FILEINFO_MIME_TYPE); + if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system + { + $file_type = $finfo->file($file['tmp_name']); + + /* According to the comments section of the PHP manual page, + * it is possible that this function returns an empty string + * for some files (e.g. if they don't exist in the magic MIME database. + */ + if (strlen($file_type) > 1) + { + $this->file_type = $file_info; + return; + } + } + } + + // Fall back to the deprecated mime_content_type(), if available + if (function_exists('mime_content_type')) + { + $this->file_type = @mime_content_type($file['tmp_name']); + return; + } + + /* This is an ugly hack, but UNIX-type systems provide a native way to detect the file type, + * which is still more secure than depending on the value of $_FILES[$field]['type']. + * + * Notes: + * - a 'W' in the substr() expression bellow, would mean that we're using Windows + * - many system admins would disable the exec() function due to security concerns, hence the function_exists() check + */ + if (substr(PHP_OS, 0, 1) !== 'W' && function_exists('exec')) + { + $output = array(); + @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code); + if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution + { + $this->file_type = rtrim($output[0]); + return; + } + } + + $this->file_type = $file['type']; + } + + // -------------------------------------------------------------------- + } // END Upload Class /* End of file Upload.php */ -/* Location: ./system/libraries/Upload.php */ \ No newline at end of file +/* Location: ./system/libraries/Upload.php */ -- cgit v1.2.3-24-g4f1b From 77870b53059d1ee3d761ee54bc5042c560430e36 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 24 Sep 2011 14:35:10 +0300 Subject: Remove an unnecessary variable initialization --- system/libraries/Upload.php | 2 -- 1 file changed, 2 deletions(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index fcfd89915..a16d5f65d 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -1020,8 +1020,6 @@ class CI_Upload { */ protected function _file_mime_type($file) { - $file_type = ''; - // Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag) if ( (float) substr(phpversion(), 0, 3) >= 5.3 && function_exists('finfo_file')) { -- cgit v1.2.3-24-g4f1b From 420fe0721944ad58a3199b31c92cd896499c8ed1 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 24 Sep 2011 14:45:44 +0300 Subject: Fix alignment with tabs instead of spaces --- system/libraries/Upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index a16d5f65d..324747e80 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -1060,7 +1060,7 @@ class CI_Upload { @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code); if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution { - $this->file_type = rtrim($output[0]); + $this->file_type = rtrim($output[0]); return; } } -- cgit v1.2.3-24-g4f1b From 2cec39f2c221d2acab5dbd830b6dd64db01b24d9 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 24 Sep 2011 22:59:37 +0300 Subject: Fix an erroneus variable name and a typo in comments --- system/libraries/Upload.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 324747e80..67551fbbd 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -1030,11 +1030,11 @@ class CI_Upload { /* According to the comments section of the PHP manual page, * it is possible that this function returns an empty string - * for some files (e.g. if they don't exist in the magic MIME database. + * for some files (e.g. if they don't exist in the magic MIME database) */ if (strlen($file_type) > 1) { - $this->file_type = $file_info; + $this->file_type = $file_type; return; } } -- cgit v1.2.3-24-g4f1b From f300fb27a54c4eb6018dffb77a5e541416ffa5c2 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 26 Sep 2011 10:27:25 +0300 Subject: Use CI's is_php() instead of comparing against phpversion() --- system/libraries/Upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 67551fbbd..fc3de0329 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -1021,7 +1021,7 @@ class CI_Upload { protected function _file_mime_type($file) { // Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag) - if ( (float) substr(phpversion(), 0, 3) >= 5.3 && function_exists('finfo_file')) + if (is_php('5.3') && function_exists('finfo_file')) { $finfo = new finfo(FILEINFO_MIME_TYPE); if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system -- cgit v1.2.3-24-g4f1b From 8b3cf634d94cdd8a11b1f1fcec69bdc2a0f5e71b Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 4 Oct 2011 18:27:32 +0300 Subject: Change Windows OS detection approach --- system/libraries/Upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Upload.php') diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index fc3de0329..045283f96 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -1054,7 +1054,7 @@ class CI_Upload { * - a 'W' in the substr() expression bellow, would mean that we're using Windows * - many system admins would disable the exec() function due to security concerns, hence the function_exists() check */ - if (substr(PHP_OS, 0, 1) !== 'W' && function_exists('exec')) + if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec')) { $output = array(); @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code); -- cgit v1.2.3-24-g4f1b