mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-19 02:56:15 +00:00
Adding very minimal and incomplete implementation of csrf consumption.
Tests added for consuming csrf tokens on each request.
This commit is contained in:
parent
dc6b33f80e
commit
711e736cd3
2 changed files with 65 additions and 8 deletions
|
@ -216,10 +216,13 @@ class SecurityComponent extends Component {
|
|||
|
||||
if ($isPost && $isRequestAction && $this->validatePost) {
|
||||
if ($this->_validatePost($controller) === false) {
|
||||
if (!$this->blackHole($controller, 'auth')) {
|
||||
return null;
|
||||
return $this->blackHole($controller, 'auth');
|
||||
}
|
||||
}
|
||||
if ($isPost && $this->csrfCheck) {
|
||||
if ($this->_validateCsrf($controller) === false) {
|
||||
return $this->blackHole($controller, 'csrf');
|
||||
}
|
||||
}
|
||||
$this->_generateToken($controller);
|
||||
}
|
||||
|
@ -434,7 +437,7 @@ class SecurityComponent extends Component {
|
|||
$code = 401;
|
||||
$controller->header($this->loginRequest());
|
||||
}
|
||||
$controller->redirect(null, $code, true);
|
||||
return $controller->redirect(null, $code, true);
|
||||
} else {
|
||||
return $this->_callback($controller, $this->blackHoleCallback, array($error));
|
||||
}
|
||||
|
@ -709,6 +712,23 @@ class SecurityComponent extends Component {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the controller has a CSRF token in the POST data
|
||||
* and that the token is legit/not expired.
|
||||
*
|
||||
* @param Controller $controller A controller to check
|
||||
* @return boolean Valid csrf token.
|
||||
*/
|
||||
protected function _validateCsrf($controller) {
|
||||
$token = $this->Session->read('_Token');
|
||||
$requestToken = $controller->request->data('_Token.nonce');
|
||||
if (isset($token['csrfTokens'][$requestToken])) {
|
||||
$this->Session->delete('_Token.csrfTokens.' . $requestToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default login options for an HTTP-authenticated request
|
||||
*
|
||||
|
|
|
@ -153,6 +153,7 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->Controller->Security = $this->Controller->TestSecurity;
|
||||
$this->Controller->Security->blackHoleCallback = 'fail';
|
||||
$this->Security = $this->Controller->Security;
|
||||
$this->Security->csrfCheck = false;
|
||||
|
||||
Configure::write('Security.salt', 'foo!');
|
||||
}
|
||||
|
@ -233,7 +234,7 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->request['action'] = 'posted';
|
||||
$this->Controller->Security->requirePost('posted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
|
@ -451,8 +452,8 @@ DIGEST;
|
|||
function testRequireGetSucceedWrongMethod() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->request['action'] = 'posted';
|
||||
$this->Controller->Security->requireGet('getted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->Security->requireGet('getted');
|
||||
$this->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
|
@ -1246,6 +1247,11 @@ DIGEST;
|
|||
$this->assertEquals(strtotime('+10 minutes'), current($token['csrfTokens']), 'Token expiry does not match');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setting multiple nonces, when startup() is called more than once, (ie more than one request.)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testCsrfSettingMultipleNonces() {
|
||||
$this->Security->validatePost = false;
|
||||
$this->Security->csrfCheck = true;
|
||||
|
@ -1259,4 +1265,35 @@ DIGEST;
|
|||
$this->assertEquals(strtotime('+10 minutes'), $expires, 'Token expiry does not match');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test that nonces are consumed by form submits.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testCsrfNonceConsumption() {
|
||||
$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(
|
||||
'nonce' => 'nonce1'
|
||||
),
|
||||
'Post' => array(
|
||||
'title' => 'Woot'
|
||||
)
|
||||
);
|
||||
$this->Security->startup($this->Controller);
|
||||
$token = $this->Security->Session->read('_Token');
|
||||
$this->assertFalse(isset($token['csrfTokens']['nonce1']), 'Token was not consumed');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue