Skip to content

Commit

Permalink
[ss-2015-026]: BUG Fix FormField error messages not being encoded safely
Browse files Browse the repository at this point in the history
  • Loading branch information
Damian Mooyman committed Nov 11, 2015
1 parent 53b3bc7 commit 245e0aa
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
25 changes: 25 additions & 0 deletions docs/en/04_Changelogs/3.1.16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 3.1.16

## Upgrading

FormField validation messages generated by the `Validator` class will now be automatically XML
encoded before being rendered alongside an invalid field.

If a validation message in a custom `Validator` instance should be rendered as literal HTML,
then the $message parameter for `Validator::validationError` should be passed as an instance
of `HTMLText`

For example:


:::php
class MyCustomValidator extends Validator {
public function php($data) {
$this->validationError(
'EmailAddress',
DBField::create_field('HTMLText', "Invalid email. Please sign up at <a href='signup'>this page</a>")
);
}
}


12 changes: 12 additions & 0 deletions forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,18 @@ public function validate(){
if($errors){
// Load errors into session and post back
$data = $this->getData();
// Encode validation messages as XML before saving into session state
// As per Form::addErrorMessage()
$errors = array_map(function($error) {
// Encode message as XML by default
if($error['message'] instanceof DBField) {
$error['message'] = $error['message']->forTemplate();;
} else {
$error['message'] = Convert::raw2xml($error['message']);
}
return $error;
}, $errors);

Session::set("FormInfo.{$this->FormName()}.errors", $errors);
Session::set("FormInfo.{$this->FormName()}.data", $data);
return false;
Expand Down
16 changes: 14 additions & 2 deletions tests/forms/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ public function testSessionValidationMessage() {
'FormTest_Controller/Form',
array(
'Email' => 'invalid',
'Number' => '<a href="http://mysite.com">link</a>' // XSS attempt
// leaving out "Required" field
)
);
Expand All @@ -243,7 +244,17 @@ public function testSessionValidationMessage() {
),
'Required fields show a notification on field when left blank'
);


$this->assertContains(
'&#039;&lt;a href=&quot;http://mysite.com&quot;&gt;link&lt;/a&gt;&#039; is not a number, only numbers can be accepted for this field',
$response->getBody(),
"Validation messages are safely XML encoded"
);
$this->assertNotContains(
'<a href="http://mysite.com">link</a>',
$response->getBody(),
"Unsafe content is not emitted directly inside the response body"
);
}

public function testSessionSuccessMessage() {
Expand Down Expand Up @@ -630,7 +641,8 @@ public function Form() {
new FieldList(
new EmailField('Email'),
new TextField('SomeRequiredField'),
new CheckboxSetField('Boxes', null, array('1'=>'one','2'=>'two'))
new CheckboxSetField('Boxes', null, array('1'=>'one','2'=>'two')),
new NumericField('Number')
),
new FieldList(
new FormAction('doSubmit')
Expand Down

0 comments on commit 245e0aa

Please sign in to comment.