diff options
author | robocoder <anthon.pang@gmail.com> | 2010-08-03 23:13:48 +0400 |
---|---|---|
committer | robocoder <anthon.pang@gmail.com> | 2010-08-03 23:13:48 +0400 |
commit | 4bdde26953dc3f1352baa3d4fa71620aad2455aa (patch) | |
tree | 6ba4996a9d74c099edc1c7879e2684af62ae1b9c /core/Cookie.php | |
parent | 588bc338946986f6473ed570607ddb972d03022f (diff) |
fix bug where numeric value would be base64 encoded; sign cookies as a more robust defense
git-svn-id: http://dev.piwik.org/svn/trunk@2856 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'core/Cookie.php')
-rw-r--r-- | core/Cookie.php | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/core/Cookie.php b/core/Cookie.php index 4745a15766..50ea785d6e 100644 --- a/core/Cookie.php +++ b/core/Cookie.php @@ -160,7 +160,25 @@ class Piwik_Cookie $this->setP3PHeader(); $this->setCookie( $this->name, $cookieString, $this->expire, $this->path); } - + + /** + * Extract signed content from string: content VALUE_SEPARATOR '_=' signature + * + * @param string $content + * @return string|false Content or false if unsigned + */ + private function extractSignedContent($content) + { + $signature = substr($content, -40); + if(substr($content, -43, 3) == self::VALUE_SEPARATOR . '_=' && + $signature == sha1(substr($content, 0, -40) . Piwik_Common::getSalt())) + { + // strip trailing: VALUE_SEPARATOR '_=' signature" + return substr($content, 0, -43); + } + return false; + } + /** * Load the cookie content into a php array. * Parses the cookie string to extract the different variables. @@ -169,7 +187,12 @@ class Piwik_Cookie */ protected function loadContentFromCookie() { - $cookieStr = $_COOKIE[$this->name]; + $cookieStr = $this->extractSignedContent($_COOKIE[$this->name]); + if($cookieStr === false) + { + return; + } + $values = explode( self::VALUE_SEPARATOR, $cookieStr); foreach($values as $nameValue) { @@ -201,16 +224,28 @@ class Piwik_Cookie $cookieStr = ''; foreach($this->value as $name=>$value) { - if(is_array($value)) + if(!is_numeric($value)) { - $value = serialize($value); + if(is_array($value)) + { + $value = serialize($value); + } + $value = base64_encode($value); } - $value = base64_encode($value); - + $cookieStr .= "$name=$value" . self::VALUE_SEPARATOR; } - $cookieStr = substr($cookieStr, 0, strlen($cookieStr)-1); - return $cookieStr; + + if(!empty($cookieStr)) + { + $cookieStr .= '_='; + + // sign cookie + $signature = sha1($cookieStr . Piwik_Common::getSalt()); + return $cookieStr . $signature; + } + + return ''; } /** |