diff --git a/cake/libs/controller/components/security.php b/cake/libs/controller/components/security.php index 10c11d3cd..e7afec2d1 100644 --- a/cake/libs/controller/components/security.php +++ b/cake/libs/controller/components/security.php @@ -114,6 +114,12 @@ class SecurityComponent extends Object { * @see SecurityComponent::requireAuth() */ var $allowedActions = array(); +/** + * Form fields to disable + * + * @var array + */ + var $disabledFields = array(); /** * Other components used by the Security component * @@ -443,10 +449,41 @@ class SecurityComponent extends Object { return null; } } - $fields = $controller->data['__Token']['fields']; + $form = $controller->data['__Token']['fields']; $check = $controller->data; unset($check['__Token']['fields']); + if(!empty($this->disabledFields)) { + foreach($check as $model => $fields) { + foreach($fields as $field => $value) { + $key[] = $model . '.' . $field; + } + unset($field); + } + + foreach($this->disabledFields as $value) { + $parts = preg_split('/\/|\./', $value); + + if (count($parts) == 1) { + $key1[] = $controller->modelClass . '.' . $parts['0']; + } elseif (count($parts) == 2) { + $key1[] = $parts['0'] . '.' . $parts['1']; + } + } + + foreach ($key1 as $value) { + + if(in_array($value, $key)) { + $remove = explode('.', $value); + unset($check[$remove['0']][$remove['1']]); + } elseif (in_array('_' . $value, $key)) { + $remove = explode('.', $value); + $controller->data[$remove['0']][$remove['1']] = $controller->data['_' . $remove['0']][$remove['1']]; + unset($check['_' . $remove['0']][$remove['1']]); + } + } + } + foreach($check as $key => $value) { if($key === '__Token') { $field[$key] = $value; @@ -464,7 +501,7 @@ class SecurityComponent extends Object { if(isset($values['0']) && empty($values['0'])) { $k = array_keys($value); if(isset($values['0'])) { - $field[$key][$k['0']] = null; + $field[$key][$k['0']] = ''; } } else { $field[$key] = $value; @@ -476,7 +513,7 @@ class SecurityComponent extends Object { } $check = urlencode(Security::hash(serialize($field) . CAKE_SESSION_STRING)); - if($fields !== $check) { + if($form !== $check) { if(!$this->blackHole($controller, 'auth')) { return null; } @@ -498,7 +535,8 @@ class SecurityComponent extends Object { $token = array('key' => $authKey, 'expires' => $expires, 'allowedControllers' => $this->allowedControllers, - 'allowedActions' => $this->allowedActions); + 'allowedActions' => $this->allowedActions, + 'disabledFields' => $this->disabledFields); if(!isset($controller->data)) { $controller->data = array(); diff --git a/cake/libs/view/helpers/form.php b/cake/libs/view/helpers/form.php index d132b83b0..b44ce3c79 100644 --- a/cake/libs/view/helpers/form.php +++ b/cake/libs/view/helpers/form.php @@ -253,6 +253,40 @@ class FormHelper extends AppHelper { $append .= '

'; return $append; } + function __secure($model = null, $options = null) { + if(!$model) { + $model = $this->model(); + } + + if(isset($this->params['_Token']) && !empty($this->params['_Token'])) { + if(!empty($this->params['_Token']['disabledFields'])) { + foreach ($this->params['_Token']['disabledFields'] as $value) { + $parts = preg_split('/\/|\./', $value); + if (count($parts) == 1) { + if($parts[0] === $this->field()) { + return; + } + } elseif (count($parts) == 2) { + if($parts[0] === $this->model() && $parts[1] === $this->field()) { + return; + } + } + } + if(!is_null($options)) { + $this->fields[$model][$this->field()] = $options; + return; + } + $this->fields[$model][] = $this->field(); + return; + } + if(!is_null($options)) { + $this->fields[$model][$this->field()] = $options; + return; + } + $this->fields[$model][] = $this->field(); + return; + } + } /** * Returns true if there is an error for the given field, otherwise false * @@ -556,7 +590,7 @@ class FormHelper extends AppHelper { * @return string An HTML text input element */ function text($fieldName, $options = array()) { - $this->fields[$this->model()][] = $this->field(); + $this->__secure(); $options = $this->__initInputField($fieldName, am(array('type' => 'text'), $options)); return $this->output(sprintf($this->Html->tags['input'], $this->model(), $this->field(), $this->_parseAttributes($options, null, null, ' '))); } @@ -568,7 +602,7 @@ class FormHelper extends AppHelper { * @return string */ function password($fieldName, $options = array()) { - $this->fields[$this->model()][] = $this->field(); + $this->__secure(); $options = $this->__initInputField($fieldName, $options); return $this->output(sprintf($this->Html->tags['password'], $this->model(), $this->field(), $this->_parseAttributes($options, null, null, ' '))); } @@ -580,7 +614,7 @@ class FormHelper extends AppHelper { * @return string An HTML text input element */ function textarea($fieldName, $options = array()) { - $this->fields[$this->model()][] = $this->field(); + $this->__secure(); $options = $this->__initInputField($fieldName, $options); unset($options['type']); $value = null; @@ -606,12 +640,12 @@ class FormHelper extends AppHelper { if(isset($this->params['_Token']) && !empty($this->params['_Token'])) { $model = '_' . $model; } - $this->fields[$model][$this->field()] = $options['value']; + $this->__secure($model, ife($options['value'], $options['value'], '')); if (in_array($fieldName, array('_method', '_fields'))) { $model = null; } - return $this->output(sprintf($this->Html->tags['hidden'], $model, $this->field(), $this->_parseAttributes($options, null, ' ', ' '))); + return $this->output(sprintf($this->Html->tags['hidden'], $model, $this->field(), $this->_parseAttributes($options, null, '', ' '))); } /** * Creates file input widget. @@ -622,7 +656,7 @@ class FormHelper extends AppHelper { * @access public */ function file($fieldName, $options = array()) { - $this->fields[$this->model()][] = $this->field(); + $this->__secure(); $options = $this->__initInputField($fieldName, $options); return $this->output(sprintf($this->Html->tags['file'], $this->model(), $this->field(), $this->_parseAttributes($options, null, '', ' '))); } @@ -727,7 +761,7 @@ class FormHelper extends AppHelper { function select($fieldName, $options = array(), $selected = null, $attributes = array(), $showEmpty = '') { $showParents = false; $this->setFormTag($fieldName); - $this->fields[$this->model()][] = $this->field(); + $this->__secure(); $attributes = $this->domId((array)$attributes); if ($this->tagIsInvalid()) {