Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.209
diff -u -p -r1.209 file.inc
--- includes/file.inc	11 May 2010 10:56:04 -0000	1.209
+++ includes/file.inc	21 May 2010 14:12:57 -0000
@@ -1167,28 +1167,39 @@ function file_save_upload($source, $vali
       return FALSE;
   }
 
-  // Build the list of non-munged extensions.
-  // @todo: this should not be here. we need to figure out the right place.
-  $extensions = '';
-  foreach ($user->roles as $rid => $name) {
-    $extensions .= ' ' . variable_get("upload_extensions_$rid",
-    variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp'));
+  // File extension validation is required for security purposes.
+  if (!in_array('file_validate_extensions', array_keys($validators))) {
+    drupal_set_message(t('You must first allow a file extension before you can upload %file.', array('%file' => $_FILES['files']['name'][$source])), 'error');
+    return FALSE;
   }
 
+  // Build the list of non-munged extensions.
+  $extensions = implode(' ', $validators['file_validate_extensions']);
+
   // Begin building file object.
   $file = new stdClass();
   $file->uid      = $user->uid;
   $file->status   = 0;
+  // Munging is required to protect against possible malicious extension hiding
+  // within an unknown file type.
+  // ie: filename.php.foo 
   $file->filename = file_munge_filename(trim(basename($_FILES['files']['name'][$source]), '.'), $extensions);
   $file->uri      = $_FILES['files']['tmp_name'][$source];
   $file->filemime = file_get_mimetype($file->filename);
   $file->filesize = $_FILES['files']['size'][$source];
 
   // Rename potentially executable files, to help prevent exploits.
-  if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
-    $file->filemime = 'text/plain';
-    $file->uri .= '.txt';
-    $file->filename .= '.txt';
+  // Don't rename if 'allow_insecure_uploads' evaluates to TRUE.
+  if (preg_match('/\.(php|pl|py|cgi|asp|js)\.|$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
+	if (!variable_get('allow_insecure_uploads', 0)) {
+      $file->filemime = 'text/plain';
+      $file->uri .= '.txt';
+      $file->filename .= '.txt';
+	  // The .txt extension may not be in the allowed list of extensions.
+      // We have to add it here or else the file upload will fail.
+      $validators['file_validate_extensions'][0] .= ' txt';
+      drupal_set_message(t('For security reasons, your upload has been renamed to %filename.', array('%filename' => $file->filename)));
+	}
   }
 
   // If the destination is not provided, use the temporary directory.
Index: modules/file/file.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/file.field.inc,v
retrieving revision 1.26
diff -u -p -r1.26 file.field.inc
--- modules/file/file.field.inc	13 Apr 2010 15:23:03 -0000	1.26
+++ modules/file/file.field.inc	21 May 2010 14:12:58 -0000
@@ -122,9 +122,10 @@ function file_field_instance_settings_fo
     '#type' => 'textfield',
     '#title' => t('Allowed file extensions'),
     '#default_value' => $extensions,
-    '#description' => t('Separate extensions with a space or comma and do not include the leading dot. Leaving this blank will allow users to upload a file with any extension.'),
+    '#description' => t('Separate extensions with a space or comma and do not include the leading dot. You must whitelist all allowed extensions for this upload field.'),
     '#element_validate' => array('_file_generic_settings_extensions'),
     '#weight' => 1,
+    '#required' => TRUE,
   );
 
   $form['max_filesize'] = array(
@@ -545,10 +546,16 @@ function file_field_widget_upload_valida
   // There is always a file size limit due to the PHP server limit.
   $validators['file_validate_size'] = array($max_filesize);
 
-  // Add the extension check if necessary.
+  // 'file_extensions' is required so it should not be empty.
+  // However if it is we can't return an error here
+  // so we fallback to the default extension setting.
   if (!empty($instance['settings']['file_extensions'])) {
     $validators['file_validate_extensions'] = array($instance['settings']['file_extensions']);
   }
+  else {
+    $default_file_field_info = file_field_info();
+    $validators['file_validate_extensions'] = array($default_file_field_info['file']['instance_settings']['file_extensions']);
+  }
 
   return $validators;
 }
