From 7f7c202f355db7b46ebd7f41c98d8d1d45c5c464 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 2 Oct 2010 17:16:40 -0400 Subject: [PATCH] Removing old CSRF token validation checks. Removing failing test because the feature moved. Adding tests for expired and wrong keys. --- cake/libs/controller/components/security.php | 26 +------ .../controller/components/security.test.php | 70 ++++++++++++++++--- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/cake/libs/controller/components/security.php b/cake/libs/controller/components/security.php index 0184312f6..cbee815e3 100644 --- a/cake/libs/controller/components/security.php +++ b/cake/libs/controller/components/security.php @@ -595,18 +595,9 @@ class SecurityComponent extends Component { } $data = $controller->request->data; - if (!isset($data['_Token']) || !isset($data['_Token']['fields']) || !isset($data['_Token']['key'])) { + if (!isset($data['_Token']) || !isset($data['_Token']['fields'])) { return false; } - $token = $data['_Token']['key']; - - if ($this->Session->check('_Token')) { - $tokenData = $this->Session->read('_Token'); - - if ($tokenData['expires'] < time() || $tokenData['key'] !== $token) { - return false; - } - } $locked = null; $check = $controller->request->data; @@ -678,10 +669,8 @@ class SecurityComponent extends Component { return false; } $authKey = Security::generateAuthKey(); - $expires = strtotime('+' . Security::inactiveMins() . ' minutes'); $token = array( 'key' => $authKey, - 'expires' => $expires, 'allowedControllers' => $this->allowedControllers, 'allowedActions' => $this->allowedActions, 'disabledFields' => $this->disabledFields, @@ -694,15 +683,6 @@ class SecurityComponent extends Component { if ($this->Session->check('_Token')) { $tokenData = $this->Session->read('_Token'); - $valid = ( - isset($tokenData['expires']) && - $tokenData['expires'] > time() && - isset($tokenData['key']) - ); - - if ($valid) { - $token['key'] = $tokenData['key']; - } if (!empty($tokenData['csrfTokens'])) { $token['csrfTokens'] += $tokenData['csrfTokens']; $token['csrfTokens'] = $this->_expireTokens($token['csrfTokens']); @@ -723,8 +703,8 @@ class SecurityComponent extends Component { */ protected function _validateCsrf($controller) { $token = $this->Session->read('_Token'); - $requestToken = $controller->request->data('_Token.nonce'); - if (isset($token['csrfTokens'][$requestToken])) { + $requestToken = $controller->request->data('_Token.key'); + if (isset($token['csrfTokens'][$requestToken]) && $token['csrfTokens'][$requestToken] >= time()) { $this->Session->delete('_Token.csrfTokens.' . $requestToken); return true; } diff --git a/cake/tests/cases/libs/controller/components/security.test.php b/cake/tests/cases/libs/controller/components/security.test.php index cd072731f..50772c645 100644 --- a/cake/tests/cases/libs/controller/components/security.test.php +++ b/cake/tests/cases/libs/controller/components/security.test.php @@ -606,14 +606,8 @@ DIGEST; ); $result = $this->Controller->Security->validatePost($this->Controller); $this->assertFalse($result, 'validatePost passed when fields were missing. %s'); - - $this->Controller->request->data = array( - 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'), - '_Token' => compact('fields') - ); - $result = $this->Controller->Security->validatePost($this->Controller); - $this->assertFalse($result, 'validatePost passed when key was missing. %s'); } + /** * Tests validation of checkbox arrays * @@ -1286,7 +1280,7 @@ DIGEST; $this->Controller->request->params['action'] = 'index'; $this->Controller->request->data = array( '_Token' => array( - 'nonce' => 'nonce1' + 'key' => 'nonce1' ), 'Post' => array( 'title' => 'Woot' @@ -1315,4 +1309,64 @@ DIGEST; $tokens = $this->Security->Session->read('_Token.csrfTokens'); $this->assertEquals(1, count($tokens), 'Too many tokens left behind'); } + +/** + * test that when the key is missing the request is blackHoled + * + * @return void + */ + function testCsrfBlackHoleOnKeyMismatch() { + $this->Security->validatePost = false; + $this->Security->csrfCheck = true; + $this->Security->csrfExpires = '+10 minutes'; + + $this->Security->Session->write('_Token.csrfTokens', array('nonce1' => strtotime('+10 minutes'))); + + $this->Controller->request = $this->getMock('CakeRequest', array('is')); + $this->Controller->request->expects($this->once())->method('is') + ->with('post') + ->will($this->returnValue(true)); + + $this->Controller->request->params['action'] = 'index'; + $this->Controller->request->data = array( + '_Token' => array( + 'key' => 'not the right value' + ), + 'Post' => array( + 'title' => 'Woot' + ) + ); + $this->Security->startup($this->Controller); + $this->assertTrue($this->Controller->failed, 'fail() was not called.'); + } + +/** + * test that when the key is missing the request is blackHoled + * + * @return void + */ + function testCsrfBlackHoleOnExpiredKey() { + $this->Security->validatePost = false; + $this->Security->csrfCheck = true; + $this->Security->csrfExpires = '+10 minutes'; + + $this->Security->Session->write('_Token.csrfTokens', array('nonce1' => strtotime('-5 minutes'))); + + $this->Controller->request = $this->getMock('CakeRequest', array('is')); + $this->Controller->request->expects($this->once())->method('is') + ->with('post') + ->will($this->returnValue(true)); + + $this->Controller->request->params['action'] = 'index'; + $this->Controller->request->data = array( + '_Token' => array( + 'key' => 'nonce1' + ), + 'Post' => array( + 'title' => 'Woot' + ) + ); + $this->Security->startup($this->Controller); + $this->assertTrue($this->Controller->failed, 'fail() was not called.'); + } }