Commit 08a480c6 by Carsten Brandt

make Request more robust against invalid CSRF data

fixes #4514
parent 4d3e0c77
...@@ -75,6 +75,7 @@ Yii Framework 2 Change Log ...@@ -75,6 +75,7 @@ Yii Framework 2 Change Log
- Bug #4453: `yii message/extract` wasn't properly writing to po files in case of multiple categories (samdark) - Bug #4453: `yii message/extract` wasn't properly writing to po files in case of multiple categories (samdark)
- Bug #4469: Make `Security::compareString()` timing depend only on length of `$actual` input and add unit test. (tom--) - Bug #4469: Make `Security::compareString()` timing depend only on length of `$actual` input and add unit test. (tom--)
- Bug #4470: Avoid endless loop when exporting logs with low values of flushInterval and eportInterval (cebe) - Bug #4470: Avoid endless loop when exporting logs with low values of flushInterval and eportInterval (cebe)
- Bug #4514: Fixed Request class crashing when empty CSRF token value is sent in cookie (cebe)
- Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark) - Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark)
- Bug: URL encoding for the route parameter added to `\yii\web\UrlManager` (klimov-paul) - Bug: URL encoding for the route parameter added to `\yii\web\UrlManager` (klimov-paul)
- Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue) - Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue)
......
...@@ -1228,12 +1228,11 @@ class Request extends \yii\base\Request ...@@ -1228,12 +1228,11 @@ class Request extends \yii\base\Request
{ {
if ($this->_csrfCookie === null) { if ($this->_csrfCookie === null) {
$this->_csrfCookie = $this->getCookies()->get($this->csrfParam); $this->_csrfCookie = $this->getCookies()->get($this->csrfParam);
if ($this->_csrfCookie === null) { if ($this->_csrfCookie === null || empty($this->_csrfCookie->value)) {
$this->_csrfCookie = $this->createCsrfCookie(); $this->_csrfCookie = $this->createCsrfCookie();
Yii::$app->getResponse()->getCookies()->add($this->_csrfCookie); Yii::$app->getResponse()->getCookies()->add($this->_csrfCookie);
} }
} }
return $this->_csrfCookie->value; return $this->_csrfCookie->value;
} }
...@@ -1277,7 +1276,7 @@ class Request extends \yii\base\Request ...@@ -1277,7 +1276,7 @@ class Request extends \yii\base\Request
if ($n1 > $n2) { if ($n1 > $n2) {
$token2 = str_pad($token2, $n1, $token2); $token2 = str_pad($token2, $n1, $token2);
} elseif ($n1 < $n2) { } elseif ($n1 < $n2) {
$token1 = str_pad($token1, $n2, $token1); $token1 = str_pad($token1, $n2, $n1 === 0 ? ' ' : $token1);
} }
return $token1 ^ $token2; return $token1 ^ $token2;
...@@ -1289,7 +1288,6 @@ class Request extends \yii\base\Request ...@@ -1289,7 +1288,6 @@ class Request extends \yii\base\Request
public function getCsrfTokenFromHeader() public function getCsrfTokenFromHeader()
{ {
$key = 'HTTP_' . str_replace('-', '_', strtoupper(self::CSRF_HEADER)); $key = 'HTTP_' . str_replace('-', '_', strtoupper(self::CSRF_HEADER));
return isset($_SERVER[$key]) ? $_SERVER[$key] : null; return isset($_SERVER[$key]) ? $_SERVER[$key] : null;
} }
...@@ -1304,7 +1302,6 @@ class Request extends \yii\base\Request ...@@ -1304,7 +1302,6 @@ class Request extends \yii\base\Request
$options = $this->csrfCookie; $options = $this->csrfCookie;
$options['name'] = $this->csrfParam; $options['name'] = $this->csrfParam;
$options['value'] = Yii::$app->getSecurity()->generateRandomString(); $options['value'] = Yii::$app->getSecurity()->generateRandomString();
return new Cookie($options); return new Cookie($options);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment