Index: includes/file.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/file.inc,v retrieving revision 1.39.2.4 diff -u -p -r1.39.2.4 file.inc --- includes/file.inc 18 May 2005 05:17:56 -0000 1.39.2.4 +++ includes/file.inc 30 Nov 2005 11:31:33 -0000 @@ -36,7 +36,7 @@ function file_create_url($path) { case FILE_DOWNLOADS_PUBLIC: return $GLOBALS['base_url'] .'/'. variable_get('file_directory_path', 'files') .'/'. str_replace('\\', '/', $path); case FILE_DOWNLOADS_PRIVATE: - return url('system/files', 'file='. $path); + return url('system/files', 'file='. $path, NULL, TRUE); } } @@ -143,8 +143,24 @@ function file_check_upload($source) { elseif ($_FILES["edit"]["name"][$source] && is_uploaded_file($_FILES["edit"]["tmp_name"][$source])) { $file = new StdClass(); $file->filename = trim(basename($_FILES["edit"]["name"][$source]), '.'); - $file->filemime = $_FILES["edit"]["type"][$source]; $file->filepath = $_FILES["edit"]["tmp_name"][$source]; + + if (function_exists('mime_content_type')) { + $file->filemime = mime_content_type($file->filepath); + if ($file->filemime != $_FILES["edit"]["type"][$source]) { + watchdog('file', t('For %file the system thinks its MIME type is %detected while the user has given %given for MIME type', array('%file' => theme('placeholder', $file->filepath), '%detected' => theme('placeholder', $file->filemime), '%given' => theme('placeholder', $_FILES['edit']['type'][$source])))); + } + } + else { + $file->filemime = $_FILES["edit"]["type"][$source]; + } + if (((substr($file->filemime, 0, 5) == 'text/' || strpos($file->filemime, 'javascript')) && (substr($file->filepath, -4) != '.txt')) || preg_match('/\.(php|pl|py|cgi|asp)$/i', $file->filename)) { + $file->filemime = 'text/plain'; + rename($file->filepath, $file->filepath .'.txt'); + $file->filepath .= '.txt'; + $file->filename .= '.txt'; + } + $file->error = $_FILES["edit"]["error"][$source]; $file->filesize = $_FILES["edit"]["size"][$source]; $file->source = $source; @@ -372,12 +388,6 @@ function file_save_upload($source, $dest } } - if (!user_access('bypass input data check') && !valid_input_data($file)) { - watchdog('security', t('Possible exploit abuse: invalid data.'), WATCHDOG_WARNING); - drupal_set_message(t('File upload failed: invalid data.'), 'error'); - return 0; - } - // Check for file upload errors. switch ($file->error) { case 0: // UPLOAD_ERR_OK @@ -416,11 +426,6 @@ function file_save_upload($source, $dest * @return A string containing the resulting filename or 0 on error */ function file_save_data($data, $dest, $replace = FILE_EXISTS_RENAME) { - if (!user_access('bypass input data check') && !valid_input_data($data)) { - watchdog('security', t('Possible exploit abuse: invalid data.'), WATCHDOG_WARNING); - drupal_set_message(t('File upload failed: invalid data.'), 'error'); - return 0; - } $temp = variable_get('file_directory_temp', FILE_DIRECTORY_TEMP); $file = tempnam($temp, 'file'); @@ -449,6 +454,10 @@ function file_transfer($source, $headers ob_end_clean(); foreach ($headers as $header) { + // we delete the newlines that are not followed by a space or a tab + // otherwise it may be possible to inject a HTTP header + // see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 + $header = preg_replace('/\r?\n(?!\t| )/', '', $header); header($header); } Index: modules/upload.module =================================================================== RCS file: /cvs/drupal/drupal/modules/upload.module,v retrieving revision 1.31.2.5 diff -u -p -r1.31.2.5 upload.module --- modules/upload.module 25 May 2005 04:28:59 -0000 1.31.2.5 +++ modules/upload.module 30 Nov 2005 11:31:35 -0000 @@ -103,7 +103,7 @@ function upload_admin() { function upload_download() { foreach ($_SESSION['file_uploads'] as $file) { if ($file->_filename == $_GET['q']) { - file_transfer($file->filepath, array('Content-Type: '. $file->filemime, 'Content-Length: '. $file->filesize)); + file_transfer($file->filepath, array('Content-Type: '. mime_header_encode($file->filemime), 'Content-Length: '. $file->filesize)); } } } @@ -114,9 +114,10 @@ function upload_file_download($file) { $result = db_query(db_rewrite_sql("SELECT f.nid, f.* FROM {files} f WHERE filepath = '%s'", 'f'), $file); if ($file = db_fetch_object($result)) { $name = mime_header_encode($file->filename); + $type = mime_header_encode($file->filemime); // Serve images and text inline for the browser to display rather than download. $disposition = ereg('^(text/|image/)', $file->filemime) ? 'inline' : 'attachment'; - return array('Content-Type: '. $file->filemime .'; name='. $name, + return array('Content-Type: '. $type .'; name='. $name, 'Content-Length: '. $file->filesize, 'Content-Disposition: '. $disposition .'; filename='. $name); } @@ -198,14 +199,6 @@ function upload_nodeapi(&$node, $op, $ar } } - // Rename possibly executable scripts to prevent accidental execution. - // Uploaded files are attachments and should be shown in their original - // form, rather than run. - if (preg_match('/\.(php|pl|py|cgi|asp)$/i', $file->filename)) { - $file->filename .= '.txt'; - $file->filemime = 'text/plain'; - } - if ($error['extension'] == count($user->roles) && $user->uid != 1) { form_set_error('upload', t('Error attaching file %name: invalid extension', array('%name' => theme('placeholder', $file->filename)))); }