Skip to content

Commit

Permalink
Adding support for nonce expiry.
Browse files Browse the repository at this point in the history
Adding simple time based nonce expiration. This does a simple cleanup on
each request, to remove stale tokens.  Tests added.
  • Loading branch information
markstory committed Oct 2, 2010
1 parent 711e736 commit a10f147
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
18 changes: 18 additions & 0 deletions cake/libs/controller/components/security.php
Expand Up @@ -705,6 +705,7 @@ protected function _generateToken(&$controller) {
}
if (!empty($tokenData['csrfTokens'])) {
$token['csrfTokens'] += $tokenData['csrfTokens'];
$token['csrfTokens'] = $this->_expireTokens($token['csrfTokens']);
}
}
$controller->request->params['_Token'] = $token;
Expand All @@ -729,6 +730,23 @@ protected function _validateCsrf($controller) {
return false;
}

/**
* Expire CSRF nonces and remove them from the valid tokens.
* Uses a simple timeout to expire the tokens.
*
* @param array $tokens An array of nonce => expires.
* @return An array of nonce => expires.
*/
protected function _expireTokens($tokens) {
$tokenExpiryTime = strtotime($this->csrfExpires);
foreach ($tokens as $nonce => $expires) {
if ($expires < $tokenExpiryTime) {
unset($tokens[$nonce]);
}
}
return $tokens;
}

/**
* Sets the default login options for an HTTP-authenticated request
*
Expand Down
19 changes: 19 additions & 0 deletions cake/tests/cases/libs/controller/components/security.test.php
Expand Up @@ -1296,4 +1296,23 @@ function testCsrfNonceConsumption() {
$token = $this->Security->Session->read('_Token');
$this->assertFalse(isset($token['csrfTokens']['nonce1']), 'Token was not consumed');
}

/**
* test that expired values in the csrfTokens are cleaned up.
*
* @return void
*/
function testCsrfNonceVacuum() {
$this->Security->validatePost = false;
$this->Security->csrfCheck = true;
$this->Security->csrfExpires = '+10 minutes';

$this->Security->Session->write('_Token.csrfTokens', array(
'poof' => strtotime('-11 minutes'),
'dust' => strtotime('-20 minutes')
));
$this->Security->startup($this->Controller);
$tokens = $this->Security->Session->read('_Token.csrfTokens');
$this->assertEquals(1, count($tokens), 'Too many tokens left behind');
}
}

0 comments on commit a10f147

Please sign in to comment.