Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.426
diff -u -p -r1.426 form.inc
--- includes/form.inc	8 Jan 2010 06:36:34 -0000	1.426
+++ includes/form.inc	24 Jan 2010 22:19:55 -0000
@@ -1353,7 +1353,15 @@ function _form_builder_handle_input_elem
   if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
     $value_callback = !empty($element['#value_callback']) ? $element['#value_callback'] : 'form_type_' . $element['#type'] . '_value';
 
-    if ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access']))) {
+    // With JavaScript or other easy hacking, input can be submitted even for
+    // elements with #access=FALSE or #disabled=TRUE. For security, these must
+    // not be processed. Forms that set #disabled=TRUE on an element do not
+    // expect input for the element, and even forms submitted with
+    // drupal_form_submit() must not be able to get around this. Forms that set
+    // #access=FALSE on an element usually allow access for some users, so forms
+    // submitted with drupal_form_submit() may bypass access restriction and be
+    // treated as high-privelege users instead.
+    if (empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])))) {
       // Get the input for the current element. NULL values in the input need to
       // be explicitly distinguished from missing input. (see below)
       $input = $form_state['input'];
@@ -1621,18 +1629,11 @@ function form_type_image_button_value($f
  */
 function form_type_checkbox_value($element, $input = FALSE) {
   if ($input !== FALSE) {
-    if (empty($element['#disabled'])) {
-      // Successful (checked) checkboxes are present with a value (possibly '0').
-      // http://www.w3.org/TR/html401/interact/forms.html#successful-controls
-      // For an unchecked checkbox, we return numeric 0, so we can explicitly
-      // test for a value different than string '0'.
-      return isset($input) ? $element['#return_value'] : 0;
-    }
-    else {
-      // Disabled form controls are not submitted by the browser. Ignore any
-      // submitted value and always return default.
-      return $element['#default_value'];
-    }
+    // Successful (checked) checkboxes are present with a value (possibly '0').
+    // http://www.w3.org/TR/html401/interact/forms.html#successful-controls
+    // For an unchecked checkbox, we return numeric 0, so we can explicitly
+    // test for a value different than string '0'.
+    return isset($input) ? $element['#return_value'] : 0;
   }
 }
 
@@ -1718,9 +1719,10 @@ function form_type_select_value($element
  *   for this element. Return nothing to use the default.
  */
 function form_type_textfield_value($element, $input = FALSE) {
-  if ($input !== FALSE) {
-    // Equate $input to the form value to ensure it's marked for
-    // validation.
+  // If something is submitted, return a string with newlines stripped. If
+  // nothing is submitted (not even an empty string), return NULL so that the
+  // element's default value is used.
+  if ($input !== FALSE && isset($input)) {
     return str_replace(array("\r", "\n"), '', $input);
   }
 }
