diff options
-rw-r--r-- | system/libraries/Upload.php | 68 | ||||
-rw-r--r-- | user_guide/changelog.html | 3 |
2 files changed, 68 insertions, 3 deletions
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 */ diff --git a/user_guide/changelog.html b/user_guide/changelog.html index 7ff2af2f5..fdf7227f3 100644 --- a/user_guide/changelog.html +++ b/user_guide/changelog.html @@ -79,7 +79,7 @@ Change Log <li>Helpers <ul> <li>Added <samp>increment_string()</samp> to <a href="helpers/string_helper.html">String Helper</a> to turn "foo" into "foo-1" or "foo-1" into "foo-2".</li> - <li>Altered form helper - made action on form_open_multipart helper function call optional. Fixes (#65)</li> + <li>Altered form helper - made action on form_open_multipart helper function call optional. Fixes (#65)</li> <li><samp>url_title()</samp> will now trim extra dashes from beginning and end.</li> <li>Improved speed of <a href="helpers/string_helper.html">String Helper</a>'s <b>random_string()</b> method</li> </ul> @@ -132,6 +132,7 @@ Change Log <li>Fixed a bug (#344) - Using schema found in <a href="libraries/sessions.html">Saving Session Data to a Database</a>, system would throw error "user_data does not have a default value" when deleting then creating a session.</li> <li>Fixed a bug (#112) - OCI8 (Oracle) driver didn't pass the configured database character set when connecting.</li> <li>Fixed a bug (#182) - OCI8 (Oracle) driver used to re-execute the statement whenever num_rows() is called.</li> + <li>Fixed a bug (#60) - Added _file_mime_type() method to the <a href="libraries/file_uploading.html">File Uploading Library</a> in order to fix a possible MIME-type injection.</li> </ul> <h2>Version 2.0.3</h2> |