Skip to content

Commit

Permalink
Update CsrfComponent to use immutable methods.
Browse files Browse the repository at this point in the history
Use immutable methods in CsrfComponent. This requires changing some
protected method return values, but that is within our BC guidelines.
  • Loading branch information
markstory committed Nov 16, 2017
1 parent a48e948 commit c0d360d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
19 changes: 12 additions & 7 deletions src/Controller/Component/CsrfComponent.php
Expand Up @@ -86,20 +86,24 @@ public function startup(Event $event)

$cookieData = $request->getCookie($cookieName);
if ($cookieData) {
$request->params['_csrfToken'] = $cookieData;
$request = $request->withParam('_csrfToken', $cookieData);
}

if ($request->is('requested')) {
$controller->request = $request;

return;
}

if ($request->is('get') && $cookieData === null) {
$this->_setCookie($request, $response);
list($request, $response) = $this->_setCookie($request, $response);
$controller->response = $response;
}
if ($request->is(['put', 'post', 'delete', 'patch']) || $request->getData()) {
$this->_validateToken($request);
unset($request->data[$this->_config['field']]);
$request = $request->withoutData($this->_config['field']);
}
$controller->request = $request;
}

/**
Expand All @@ -122,22 +126,23 @@ public function implementedEvents()
*
* @param \Cake\Http\ServerRequest $request The request object.
* @param \Cake\Http\Response $response The response object.
* @return void
* @return array An array of the modified request, response.
*/
protected function _setCookie(ServerRequest $request, Response $response)
{
$expiry = new Time($this->_config['expiry']);
$value = hash('sha512', Security::randomBytes(16), false);

$request->params['_csrfToken'] = $value;
$response->cookie([
'name' => $this->_config['cookieName'],
$request = $request->withParam('_csrfToken', $value);
$response = $response->withCookie($this->_config['cookieName'], [
'value' => $value,
'expire' => $expiry->format('U'),
'path' => $request->getAttribute('webroot'),
'secure' => $this->_config['secure'],
'httpOnly' => $this->_config['httpOnly'],
]);

return [$request, $response];
}

/**
Expand Down
8 changes: 4 additions & 4 deletions tests/TestCase/Controller/Component/CsrfComponentTest.php
Expand Up @@ -75,13 +75,13 @@ public function testSettingCookie()
$event = new Event('Controller.startup', $controller);
$this->component->startup($event);

$cookie = $controller->response->cookie('csrfToken');
$cookie = $controller->response->getCookie('csrfToken');
$this->assertNotEmpty($cookie, 'Should set a token.');
$this->assertRegExp('/^[a-f0-9]+$/', $cookie['value'], 'Should look like a hash.');
$this->assertEquals(0, $cookie['expire'], 'session duration.');
$this->assertEquals('/dir/', $cookie['path'], 'session path.');

$this->assertEquals($cookie['value'], $controller->request->params['_csrfToken']);
$this->assertEquals($cookie['value'], $controller->request->getParam('_csrfToken'));
}

/**
Expand Down Expand Up @@ -343,8 +343,8 @@ public function testConfigurationCookieCreate()
$event = new Event('Controller.startup', $controller);
$component->startup($event);

$this->assertEmpty($controller->response->cookie('csrfToken'));
$cookie = $controller->response->cookie('token');
$this->assertEmpty($controller->response->getCookie('csrfToken'));
$cookie = $controller->response->getCookie('token');
$this->assertNotEmpty($cookie, 'Should set a token.');
$this->assertRegExp('/^[a-f0-9]+$/', $cookie['value'], 'Should look like a hash.');
$this->assertWithinRange((new Time('+1 hour'))->format('U'), $cookie['expire'], 1, 'session duration.');
Expand Down

0 comments on commit c0d360d

Please sign in to comment.