From b1dad6e5bd1e03ab34fd0ff2b05c23971b9a9440 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 24 Sep 2011 22:35:21 -0400 Subject: [PATCH] Adding session renewal upon login/logout. This helps improve session security, as it reduces the opportunity of replaying a session id successfully. Fixes #836 --- lib/Cake/Controller/Component/AuthComponent.php | 8 ++++++-- .../Test/Case/Controller/Component/AuthComponentTest.php | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Controller/Component/AuthComponent.php b/lib/Cake/Controller/Component/AuthComponent.php index cbc72501e..777fd9faf 100644 --- a/lib/Cake/Controller/Component/AuthComponent.php +++ b/lib/Cake/Controller/Component/AuthComponent.php @@ -491,7 +491,8 @@ class AuthComponent extends Component { /** * Log a user in. If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not * specified, the request will be used to identify a user. If the identification was successful, - * the user record is written to the session key specified in AuthComponent::$sessionKey. + * the user record is written to the session key specified in AuthComponent::$sessionKey. Logging in + * will also change the session id in order to help mitigate session replays. * * @param mixed $user Either an array of user data, or null to identify a user using the current request. * @return boolean True on login success, false on failure @@ -504,6 +505,7 @@ class AuthComponent extends Component { $user = $this->identify($this->request, $this->response); } if ($user) { + $this->Session->renew(); $this->Session->write(self::$sessionKey, $user); } return $this->loggedIn(); @@ -513,7 +515,8 @@ class AuthComponent extends Component { * Logs a user out, and returns the login action to redirect to. * Triggers the logout() method of all the authenticate objects, so they can perform * custom logout logic. AuthComponent will remove the session data, so - * there is no need to do that in an authentication object. + * there is no need to do that in an authentication object. Logging out + * will also renew the session id. This helps mitigate issues with session replays. * * @return string AuthComponent::$logoutRedirect * @see AuthComponent::$logoutRedirect @@ -530,6 +533,7 @@ class AuthComponent extends Component { } $this->Session->delete(self::$sessionKey); $this->Session->delete('Auth.redirect'); + $this->Session->renew(); return Router::normalize($this->logoutRedirect); } diff --git a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php index d31db84dc..0b03f608f 100644 --- a/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php @@ -385,6 +385,8 @@ class AuthComponentTest extends CakeTestCase { 'userModel' => 'AuthUser' ) ); + $this->Auth->Session = $this->getMock('SessionComponent', array('renew'), array(), '', false); + $mocks = $this->Auth->constructAuthenticate(); $this->mockObjects[] = $mocks[0]; @@ -405,6 +407,9 @@ class AuthComponentTest extends CakeTestCase { ->with($this->Auth->request) ->will($this->returnValue($user)); + $this->Auth->Session->expects($this->once()) + ->method('renew'); + $result = $this->Auth->login(); $this->assertTrue($result);