Commit a83352a1 authored by catch's avatar catch

Issue #2174443 by mr.baileys, David_Rothstein: Add security hardening...

Issue #2174443 by mr.baileys, David_Rothstein: Add security hardening protection option for programmatic form submissions to Drupal 8 (and backport to Drupal 6?).
parent 626369a8
......@@ -304,6 +304,7 @@ public function getFormStateDefaults() {
'submitted' => FALSE,
'executed' => FALSE,
'programmed' => FALSE,
'programmed_bypass_access_check' => TRUE,
'cache'=> FALSE,
'method' => 'post',
'groups' => array(),
......@@ -1511,7 +1512,7 @@ protected function handleInputElement($form_id, &$element, &$form_state) {
// #access=FALSE on an element usually allow access for some users, so forms
// submitted with self::submitForm() may bypass access restriction and be
// treated as high-privilege users instead.
$process_input = empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
$process_input = empty($element['#disabled']) && (($form_state['programmed'] && $form_state['programmed_bypass_access_check']) || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
// Set the element's #value property.
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
......
......@@ -164,6 +164,12 @@ public function getForm($form_arg);
* likely to occur during Ajax operations.
* - programmed: If TRUE, the form was submitted programmatically, usually
* invoked via self::submitForm(). Defaults to FALSE.
* - programmed_bypass_access_check: If TRUE, programmatic form submissions
* are processed without taking #access into account. Set this to FALSE
* when submitting a form programmatically with values that may have been
* input by the user executing the current request; this will cause
* #access to be respected as it would on a normal form submission.
* Defaults to TRUE.
* - process_input: Boolean flag. TRUE signifies correct form submission.
* This is always TRUE for programmed forms coming from self::submitForm()
* (see 'programmed' key), or if the form_id coming from the
......
......@@ -95,8 +95,35 @@ private function submitForm($values, $valid_input) {
// submission handler was properly executed.
$stored_values = $form_state['storage']['programmatic_form_submit'];
foreach ($values as $key => $value) {
$this->assertTrue(isset($stored_values[$key]) && $stored_values[$key] == $value, format_string('Submission handler correctly executed: %stored_key is %stored_value', array('%stored_key' => $key, '%stored_value' => print_r($value, TRUE))));
$this->assertEqual($stored_values[$key], $value, format_string('Submission handler correctly executed: %stored_key is %stored_value', array('%stored_key' => $key, '%stored_value' => print_r($value, TRUE))));
}
}
}
/**
* Test the programmed_bypass_access_check flag.
*/
public function testProgrammaticAccessBypass() {
$form_state['values'] = array(
'textfield' => 'dummy value',
'field_restricted' => 'dummy value'
);
// Programmatically submit the form with a value for the restricted field.
// Since programmed_bypass_access_check is set to TRUE by default, the
// field is accessible and can be set.
\Drupal::formBuilder()->submitForm('form_test_programmatic_form', $form_state);
$values = $form_state['storage']['programmatic_form_submit'];
$this->assertEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is stored correctly.');
// Programmatically submit the form with a value for the restricted field
// with programmed_bypass_access_check set to FALSE. Since access
// restrictions apply, the restricted field is inaccessible, and the value
// should not be stored.
$form_state['programmed_bypass_access_check'] = FALSE;
\Drupal::formBuilder()->submitForm('form_test_programmatic_form', $form_state);
$values = $form_state['storage']['programmatic_form_submit'];
$this->assertNotEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is not stored.');
}
}
......@@ -1768,6 +1768,12 @@ function form_test_programmatic_form($form, &$form_state) {
'#default_value' => 'all',
);
$form['field_restricted'] = array(
'#type' => 'textfield',
'#title' => 'Textfield (no access)',
'#access' => FALSE,
);
// The main submit button for the form.
$form['submit'] = array(
'#type' => 'submit',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment