Skip to content

Commit

Permalink
Merge pull request #2835 from kinglozzer/1891-csrf-friendly-error
Browse files Browse the repository at this point in the history
NEW: Forms with invalid/expired SecurityIDs are repopulated (fixes #1891)
  • Loading branch information
chillu committed Feb 11, 2014
2 parents b9ee4c4 + 058219c commit 5e38ef9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
18 changes: 14 additions & 4 deletions forms/Form.php
Expand Up @@ -277,10 +277,20 @@ public function httpSubmission($request) {

// Protection against CSRF attacks
$token = $this->getSecurityToken();
if(!$token->checkRequest($request)) {
$this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE",
"There seems to have been a technical problem. Please click the back button,"
. " refresh your browser, and try again."));
if( ! $token->checkRequest($request)) {
if (empty($vars['SecurityID'])) {
$this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE",
"There seems to have been a technical problem. Please click the back button,
refresh your browser, and try again."));
} else {
Session::set("FormInfo.{$this->FormName()}.data", $this->getData());
Session::set("FormInfo.{$this->FormName()}.errors", array());
$this->sessionMessage(
_t("Form.CSRF_EXPIRED_MESSAGE", "Your session has expired. Please re-submit the form."),
"warning"
);
return $this->controller->redirectBack();
}
}

// Determine the action button clicked
Expand Down
17 changes: 16 additions & 1 deletion tests/forms/FormTest.php
Expand Up @@ -311,7 +311,22 @@ public function testDisableSecurityTokenAcceptsSubmissionWithoutToken() {
)
);
$this->assertEquals(400, $response->getStatusCode(), 'Submission fails without security token');


$response = $this->get('FormTest_ControllerWithSecurityToken');
$response = $this->post(
'FormTest_ControllerWithSecurityToken/Form',
array(
'Email' => 'test@test.com',
'action_doSubmit' => 1,
'SecurityID' => -1
)
);
$this->assertEquals(200, $response->getStatusCode(), 'Submission reloads form if security token invalid');

$matched = $this->cssParser()->getBySelector('#Form_Form_Email');
$attrs = $matched[0]->attributes();
$this->assertEquals('test@test.com', (string)$attrs['value'], 'Submitted data is preserved');

$response = $this->get('FormTest_ControllerWithSecurityToken');
$tokenEls = $this->cssParser()->getBySelector('#Form_Form_SecurityID');
$this->assertEquals(
Expand Down

0 comments on commit 5e38ef9

Please sign in to comment.