mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-31 17:16:18 +00:00
Merge branch 'generate-token' into 2.1
This commit is contained in:
commit
c6f492d947
2 changed files with 67 additions and 11 deletions
|
@ -157,6 +157,19 @@ class SecurityComponent extends Component {
|
||||||
*/
|
*/
|
||||||
public $csrfUseOnce = true;
|
public $csrfUseOnce = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control the number of tokens a user can keep open.
|
||||||
|
* This is most useful with one-time use tokens. Since new tokens
|
||||||
|
* are created on each request, having a hard limit on the number of open tokens
|
||||||
|
* can be useful in controlling the size of the session file.
|
||||||
|
*
|
||||||
|
* When tokens are evicted, the oldest ones will be removed, as they are the most likely
|
||||||
|
* to be dead/expired.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $csrfLimit = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Other components used by the Security component
|
* Other components used by the Security component
|
||||||
*
|
*
|
||||||
|
@ -207,7 +220,7 @@ class SecurityComponent extends Component {
|
||||||
return $this->blackHole($controller, 'csrf');
|
return $this->blackHole($controller, 'csrf');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->_generateToken($controller);
|
$this->generateToken($controller->request);
|
||||||
if ($isPost) {
|
if ($isPost) {
|
||||||
unset($controller->request->data['_Token']);
|
unset($controller->request->data['_Token']);
|
||||||
}
|
}
|
||||||
|
@ -469,16 +482,15 @@ class SecurityComponent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add authentication key for new form posts
|
* Manually add CSRF token information into the provided request object.
|
||||||
*
|
*
|
||||||
* @param Controller $controller Instantiating controller
|
* @param CakeRequest $request The request object to add into.
|
||||||
* @return boolean Success
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
protected function _generateToken($controller) {
|
public function generateToken(CakeRequest $request) {
|
||||||
if (isset($controller->request->params['requested']) && $controller->request->params['requested'] === 1) {
|
if (isset($request->params['requested']) && $request->params['requested'] === 1) {
|
||||||
if ($this->Session->check('_Token')) {
|
if ($this->Session->check('_Token')) {
|
||||||
$tokenData = $this->Session->read('_Token');
|
$request->params['_Token'] = $this->Session->read('_Token');
|
||||||
$controller->request->params['_Token'] = $tokenData;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -498,15 +510,15 @@ class SecurityComponent extends Component {
|
||||||
$token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
|
$token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->csrfCheck && ($this->csrfUseOnce || empty($token['csrfTokens'])) ) {
|
if ($this->csrfUseOnce || empty($token['csrfTokens'])) {
|
||||||
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
|
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
|
||||||
}
|
}
|
||||||
if ($this->csrfCheck && $this->csrfUseOnce == false) {
|
if (!$this->csrfUseOnce) {
|
||||||
$csrfTokens = array_keys($token['csrfTokens']);
|
$csrfTokens = array_keys($token['csrfTokens']);
|
||||||
$token['key'] = $csrfTokens[0];
|
$token['key'] = $csrfTokens[0];
|
||||||
}
|
}
|
||||||
$this->Session->write('_Token', $token);
|
$this->Session->write('_Token', $token);
|
||||||
$controller->request->params['_Token'] = array(
|
$request->params['_Token'] = array(
|
||||||
'key' => $token['key'],
|
'key' => $token['key'],
|
||||||
'unlockedFields' => $token['unlockedFields']
|
'unlockedFields' => $token['unlockedFields']
|
||||||
);
|
);
|
||||||
|
@ -542,6 +554,10 @@ class SecurityComponent extends Component {
|
||||||
*/
|
*/
|
||||||
protected function _expireTokens($tokens) {
|
protected function _expireTokens($tokens) {
|
||||||
$now = time();
|
$now = time();
|
||||||
|
$overflow = count($tokens) - $this->csrfLimit;
|
||||||
|
if ($overflow > 0) {
|
||||||
|
$tokens = array_slice($tokens, $overflow + 1, null, true);
|
||||||
|
}
|
||||||
foreach ($tokens as $nonce => $expires) {
|
foreach ($tokens as $nonce => $expires) {
|
||||||
if ($expires < $now) {
|
if ($expires < $now) {
|
||||||
unset($tokens[$nonce]);
|
unset($tokens[$nonce]);
|
||||||
|
|
|
@ -1277,4 +1277,44 @@ class SecurityComponentTest extends CakeTestCase {
|
||||||
$token = $this->Security->Session->read('_Token');
|
$token = $this->Security->Session->read('_Token');
|
||||||
$this->assertTrue(isset($token['csrfTokens']['nonce1']), 'Token was consumed');
|
$this->assertTrue(isset($token['csrfTokens']['nonce1']), 'Token was consumed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test generateToken()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testGenerateToken() {
|
||||||
|
$request = $this->Controller->request;
|
||||||
|
$this->Security->generateToken($request);
|
||||||
|
|
||||||
|
$this->assertNotEmpty($request->params['_Token']);
|
||||||
|
$this->assertTrue(isset($request->params['_Token']['unlockedFields']));
|
||||||
|
$this->assertTrue(isset($request->params['_Token']['key']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the limiting of CSRF tokens.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCsrfLimit() {
|
||||||
|
$this->Security->csrfLimit = 3;
|
||||||
|
$time = strtotime('+10 minutes');
|
||||||
|
$tokens = array(
|
||||||
|
'1' => $time,
|
||||||
|
'2' => $time,
|
||||||
|
'3' => $time,
|
||||||
|
'4' => $time,
|
||||||
|
'5' => $time,
|
||||||
|
);
|
||||||
|
$this->Security->Session->write('_Token', array('csrfTokens' => $tokens));
|
||||||
|
$this->Security->generateToken($this->Controller->request);
|
||||||
|
$result = $this->Security->Session->read('_Token.csrfTokens');
|
||||||
|
|
||||||
|
$this->assertFalse(isset($result['1']));
|
||||||
|
$this->assertFalse(isset($result['2']));
|
||||||
|
$this->assertFalse(isset($result['3']));
|
||||||
|
$this->assertTrue(isset($result['4']));
|
||||||
|
$this->assertTrue(isset($result['5']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue