Security: add check on security token in settings.php when there are no other errors (potential CSRF) - refs BT#21427

pull/5191/head
Yannick Warnier 2 years ago committed by GitHub
commit c88d336d0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 175
      main/inc/lib/pear/HTML/QuickForm.php

@ -1417,116 +1417,119 @@ class HTML_QuickForm extends HTML_Common
*/
public function validate()
{
if (count($this->_rules) == 0 && count($this->_formRules) == 0 && $this->isSubmitted()) {
return (0 == count($this->_errors));
} elseif (!$this->isSubmitted()) {
if (!$this->isSubmitted()) {
return false;
}
if (null !== $this->getToken()) {
$check = Security::check_token('form', $this);
Security::clear_token();
if (false === $check) {
// Redirect to the same URL + show token not validated message.
$url = $this->getAttribute('action');
Display::addFlash(Display::return_message(get_lang('NotValidated'), 'warning'));
api_location($url);
return false;
}
}
$registry =& HTML_QuickForm_RuleRegistry::singleton();
if (count($this->_rules) > 0 || count($this->_formRules) > 0) {
$registry =& HTML_QuickForm_RuleRegistry::singleton();
foreach ($this->_rules as $target => $rules) {
$submitValue = $this->getSubmitValue($target);
foreach ($this->_rules as $target => $rules) {
$submitValue = $this->getSubmitValue($target);
foreach ($rules as $rule) {
if ((isset($rule['group']) && isset($this->_errors[$rule['group']])) ||
isset($this->_errors[$target])) {
continue 2;
}
// If element is not required and is empty, we shouldn't validate it
if (!$this->isElementRequired($target)) {
if (!isset($submitValue) || '' == $submitValue) {
foreach ($rules as $rule) {
if ((isset($rule['group']) && isset($this->_errors[$rule['group']])) ||
isset($this->_errors[$target])) {
continue 2;
// Fix for bug #3501: we shouldn't validate not uploaded files, either.
// Unfortunately, we can't just use $element->isUploadedFile() since
// the element in question can be buried in group. Thus this hack.
// See also bug #12014, we should only consider a file that has
// status UPLOAD_ERR_NO_FILE as not uploaded, in all other cases
// validation should be performed, so that e.g. 'maxfilesize' rule
// will display an error if status is UPLOAD_ERR_INI_SIZE
// or UPLOAD_ERR_FORM_SIZE
} elseif (is_array($submitValue)) {
if (false === ($pos = strpos($target, '['))) {
$isUpload = !empty($this->_submitFiles[$target]);
} else {
$base = str_replace(
array('\\', '\''), array('\\\\', '\\\''),
substr($target, 0, $pos)
);
$idx = "['" . str_replace(
array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
substr($target, $pos + 1, -1)
) . "']";
eval("\$isUpload = isset(\$this->_submitFiles['{$base}']['name']{$idx});");
}
if ($isUpload && (!isset($submitValue['error']) || UPLOAD_ERR_NO_FILE == $submitValue['error'])) {
}
// If element is not required and is empty, we shouldn't validate it
if (!$this->isElementRequired($target)) {
if (!isset($submitValue) || '' == $submitValue) {
continue 2;
// Fix for bug #3501: we shouldn't validate not uploaded files, either.
// Unfortunately, we can't just use $element->isUploadedFile() since
// the element in question can be buried in group. Thus this hack.
// See also bug #12014, we should only consider a file that has
// status UPLOAD_ERR_NO_FILE as not uploaded, in all other cases
// validation should be performed, so that e.g. 'maxfilesize' rule
// will display an error if status is UPLOAD_ERR_INI_SIZE
// or UPLOAD_ERR_FORM_SIZE
} elseif (is_array($submitValue)) {
if (false === ($pos = strpos($target, '['))) {
$isUpload = !empty($this->_submitFiles[$target]);
} else {
$base = str_replace(
array('\\', '\''), array('\\\\', '\\\''),
substr($target, 0, $pos)
);
$idx = "['" . str_replace(
array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
substr($target, $pos + 1, -1)
) . "']";
eval("\$isUpload = isset(\$this->_submitFiles['{$base}']['name']{$idx});");
}
if ($isUpload && (!isset($submitValue['error']) || UPLOAD_ERR_NO_FILE == $submitValue['error'])) {
continue 2;
}
}
}
}
if (isset($rule['dependent'])) {
$values = array($submitValue);
if (is_array($rule['dependent'])) {
foreach ($rule['dependent'] as $elName) {
$values[] = $this->getSubmitValue($elName);
if (isset($rule['dependent'])) {
$values = array($submitValue);
if (is_array($rule['dependent'])) {
foreach ($rule['dependent'] as $elName) {
$values[] = $this->getSubmitValue($elName);
}
} else {
$values[] = $rule['dependent'];
}
$result = $registry->validate(
$rule['type'],
$values,
$rule['format'],
true
);
} elseif (is_array($submitValue) && !isset($rule['howmany'])) {
$result = $registry->validate($rule['type'], $submitValue, $rule['format'], true);
} else {
$values[] = $rule['dependent'];
$result = $registry->validate(
$rule['type'],
$submitValue,
$rule['format'],
false
);
}
if (!$result || (!empty($rule['howmany']) && $rule['howmany'] > (int)$result)) {
if (isset($rule['group'])) {
$this->_errors[$rule['group']] = $rule['message'];
} else {
$this->_errors[$target] = $rule['message'];
}
}
$result = $registry->validate(
$rule['type'],
$values,
$rule['format'],
true
);
} elseif (is_array($submitValue) && !isset($rule['howmany'])) {
$result = $registry->validate($rule['type'], $submitValue, $rule['format'], true);
} else {
$result = $registry->validate(
$rule['type'],
$submitValue,
$rule['format'],
false
);
}
}
if (!$result || (!empty($rule['howmany']) && $rule['howmany'] > (int)$result)) {
if (isset($rule['group'])) {
$this->_errors[$rule['group']] = $rule['message'];
// process the global rules now
foreach ($this->_formRules as $rule) {
if (true !== ($res = call_user_func($rule, $this->_submitValues, $this->_submitFiles))) {
if (is_array($res)) {
$this->_errors += $res;
} else {
$this->_errors[$target] = $rule['message'];
throw new \Exception('Form rule callback returned invalid value in HTML_QuickForm::validate()');
}
}
}
if (count($this->_errors) > 0) {
return false;
}
}
// process the global rules now
foreach ($this->_formRules as $rule) {
if (true !== ($res = call_user_func($rule, $this->_submitValues, $this->_submitFiles))) {
if (is_array($res)) {
$this->_errors += $res;
} else {
throw new \Exception('Form rule callback returned invalid value in HTML_QuickForm::validate()');
}
if (null !== $this->getToken()) {
$check = Security::check_token('form', $this);
Security::clear_token();
if (false === $check) {
// Redirect to the same URL + show token not validated message.
$url = $this->getAttribute('action');
Display::addFlash(Display::return_message(get_lang('NotValidated'), 'warning'));
api_location($url);
return false;
}
}
return (0 == count($this->_errors));
return true;
}
/**

Loading…
Cancel
Save