diff --git a/src/Controller/Component/CsrfComponent.php b/src/Controller/Component/CsrfComponent.php index 08c3040d645..0a8e611b05d 100644 --- a/src/Controller/Component/CsrfComponent.php +++ b/src/Controller/Component/CsrfComponent.php @@ -144,6 +144,10 @@ protected function _validateToken(Request $request) $post = $request->data($this->_config['field']); $header = $request->header('X-CSRF-Token'); + if (empty($cookie)) { + throw new ForbiddenException(__d('cake', 'Invalid CSRF token.')); + } + if ($post !== $cookie && $header !== $cookie) { throw new ForbiddenException(__d('cake', 'Invalid CSRF token.')); } diff --git a/tests/TestCase/Controller/Component/CsrfComponentTest.php b/tests/TestCase/Controller/Component/CsrfComponentTest.php index 0c8c3442602..30bfd7e7ae7 100644 --- a/tests/TestCase/Controller/Component/CsrfComponentTest.php +++ b/tests/TestCase/Controller/Component/CsrfComponentTest.php @@ -163,7 +163,6 @@ public function testValidTokenRequestData($method) * @dataProvider httpMethodProvider * @expectedException \Cake\Network\Exception\ForbiddenException * @return void - * @triggers Controller.startup $controller */ public function testInvalidTokenRequestData($method) { @@ -180,6 +179,49 @@ public function testInvalidTokenRequestData($method) $this->component->startup($event); } + /** + * Test that missing post field fails + * + * @expectedException \Cake\Network\Exception\ForbiddenException + * @return void + */ + public function testInvalidTokenRequestDataMissing() + { + $_SERVER['REQUEST_METHOD'] = 'POST'; + + $controller = $this->getMock('Cake\Controller\Controller', ['redirect']); + $controller->request = new Request([ + 'post' => [], + 'cookies' => ['csrfToken' => 'testing123'] + ]); + $controller->response = new Response(); + + $event = new Event('Controller.startup', $controller); + $this->component->startup($event); + } + + /** + * Test that missing header and cookie fails + * + * @dataProvider httpMethodProvider + * @expectedException \Cake\Network\Exception\ForbiddenException + * @return void + */ + public function testInvalidTokenMissingCookie($method) + { + $_SERVER['REQUEST_METHOD'] = $method; + + $controller = $this->getMock('Cake\Controller\Controller', ['redirect']); + $controller->request = new Request([ + 'post' => ['_csrfToken' => 'could-be-valid'], + 'cookies' => [] + ]); + $controller->response = new Response(); + + $event = new Event('Controller.startup', $controller); + $this->component->startup($event); + } + /** * Test that CSRF checks are not applied to request action requests. *