From 4eac00a009cb9c8188be2948fe684ebb66c2550a Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 25 Sep 2012 16:43:58 -0400 Subject: [PATCH] Use hash_hmac on cookie hashes. --- laravel/cookie.php | 19 +++++++++++++++---- laravel/tests/cases/cookie.test.php | 6 +++--- laravel/tests/cases/session.test.php | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/laravel/cookie.php b/laravel/cookie.php index 21c67bb7..56077ff7 100644 --- a/laravel/cookie.php +++ b/laravel/cookie.php @@ -80,7 +80,7 @@ public static function put($name, $value, $expiration = 0, $path = '/', $domain $expiration = time() + ($expiration * 60); } - $value = sha1($value.Config::get('application.key')).'+'.$value; + $value = static::hash($value).'+'.$value; // If the secure option is set to true, yet the request is not over HTTPS // we'll throw an exception to let the developer know that they are @@ -127,6 +127,17 @@ public static function forget($name, $path = '/', $domain = null, $secure = fals return static::put($name, null, -2000, $path, $domain, $secure); } + /** + * Hash the given cookie value. + * + * @param string $value + * @return string + */ + public static function hash($value) + { + return hash_hmac('sha1', $value, Config::get('application.key')); + } + /** * Parse a hash fingerprinted cookie value. * @@ -142,7 +153,7 @@ protected static function parse($value) // ahead and throw exceptions now since there the cookie is invalid. if ( ! (count($segments) >= 2)) { - throw new \Exception("Cookie was not set by application."); + return null; } $value = implode('+', array_slice($segments, 1)); @@ -150,12 +161,12 @@ protected static function parse($value) // Now we will check if the SHA-1 hash present in the first segment matches // the ShA-1 hash of the rest of the cookie value, since the hash should // have been set when the cookie was first created by the application. - if ($segments[0] == sha1($value.Config::get('application.key'))) + if ($segments[0] == static::hash($value)) { return $value; } - throw new \Exception("Cookie has been modified by client."); + return null; } } diff --git a/laravel/tests/cases/cookie.test.php b/laravel/tests/cases/cookie.test.php index e17070b0..37d63553 100644 --- a/laravel/tests/cases/cookie.test.php +++ b/laravel/tests/cases/cookie.test.php @@ -67,7 +67,7 @@ protected function restartRequest() */ public function testHasMethodIndicatesIfCookieInSet() { - Cookie::$jar['foo'] = array('value' => sha1('bar'.Config::get('application.key')).'+bar'); + Cookie::$jar['foo'] = array('value' => Cookie::hash('bar').'+bar'); $this->assertTrue(Cookie::has('foo')); $this->assertFalse(Cookie::has('bar')); @@ -82,7 +82,7 @@ public function testHasMethodIndicatesIfCookieInSet() */ public function testGetMethodCanReturnValueOfCookies() { - Cookie::$jar['foo'] = array('value' => sha1('bar'.Config::get('application.key')).'+bar'); + Cookie::$jar['foo'] = array('value' => Cookie::hash('bar').'+bar'); $this->assertEquals('bar', Cookie::get('foo')); Cookie::put('bar', 'baz'); @@ -97,7 +97,7 @@ public function testGetMethodCanReturnValueOfCookies() public function testForeverShouldUseATonOfMinutes() { Cookie::forever('foo', 'bar'); - $this->assertEquals(sha1('bar'.Config::get('application.key')).'+bar', Cookie::$jar['foo']['value']); + $this->assertEquals(Cookie::hash('bar').'+bar', Cookie::$jar['foo']['value']); // Shouldn't be able to test this cause while we indicate -2000 seconds // cookie expiration store timestamp. diff --git a/laravel/tests/cases/session.test.php b/laravel/tests/cases/session.test.php index b46b5ba0..f93ce9b1 100644 --- a/laravel/tests/cases/session.test.php +++ b/laravel/tests/cases/session.test.php @@ -372,7 +372,7 @@ public function testSaveMethodSetsCookieWithCorrectValues() $cookie = Cookie::$jar[Config::get('session.cookie')]; - $this->assertEquals(sha1('foo'.Config::get('application.key')).'+foo', $cookie['value']); + $this->assertEquals(Cookie::hash('foo').'+foo', $cookie['value']); // Shouldn't be able to test this cause session.lifetime store number of minutes // while cookie expiration store timestamp when it going to expired. // $this->assertEquals(Config::get('session.lifetime'), $cookie['expiration']);