diff --git a/apps/advanced/backend/config/main.php b/apps/advanced/backend/config/main.php index 368f5e2..41261f6 100644 --- a/apps/advanced/backend/config/main.php +++ b/apps/advanced/backend/config/main.php @@ -14,7 +14,7 @@ return [ 'modules' => [], 'components' => [ 'request' => [ - // a secret key used to validate cookies. You may modify this key with your own one. + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', ], 'user' => [ diff --git a/apps/advanced/frontend/config/main.php b/apps/advanced/frontend/config/main.php index e57850d..1e442b3 100644 --- a/apps/advanced/frontend/config/main.php +++ b/apps/advanced/frontend/config/main.php @@ -13,7 +13,7 @@ return [ 'controllerNamespace' => 'frontend\controllers', 'components' => [ 'request' => [ - // a secret key used to validate cookies. You may modify this key with your own one. + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', ], 'user' => [ diff --git a/apps/basic/config/web.php b/apps/basic/config/web.php index 7939437..1632a5a 100644 --- a/apps/basic/config/web.php +++ b/apps/basic/config/web.php @@ -8,7 +8,7 @@ $config = [ 'bootstrap' => ['log'], 'components' => [ 'request' => [ - // a secret key used to validate cookies. You may modify this key with your own one. + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', ], 'cache' => [ diff --git a/docs/guide/start-installation.md b/docs/guide/start-installation.md index e1c8a4e..88757ae 100644 --- a/docs/guide/start-installation.md +++ b/docs/guide/start-installation.md @@ -42,6 +42,13 @@ Installing Yii from an archive file involves two steps: 1. Download the archive file from [yiiframework.com](http://www.yiiframework.com/download/yii2-basic). 2. Unpack the downloaded file to a Web-accessible folder. +3. Modify the `config/web.php` file by entering a secret key for the `cookieValidationKey` configuration item + (this is done automatically if you are installing Yii using Composer): + + ```php + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation + 'cookieValidationKey' => 'enter your secret key here', + ``` Other Installation Options <a name="other-installation-options"></a> diff --git a/extensions/composer/Installer.php b/extensions/composer/Installer.php index 25f0a69..44c91ff 100644 --- a/extensions/composer/Installer.php +++ b/extensions/composer/Installer.php @@ -273,7 +273,7 @@ EOF $key = self::generateRandomString(); foreach ((array) $extra[self::EXTRA_CONFIG] as $config) { if (is_file($config)) { - $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/i', "\\1'$key'", file_get_contents($config)); + $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($config)); file_put_contents($config, $content); } } diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 47bec67..728aeed 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -188,7 +188,7 @@ Yii Framework 2 Change Log - Chg: Changed the default value of the `keyPrefix` property of cache components to be null (qiangxue) - Chg: Added `prefix` column to `yii\log\DbTarget` to have the same amount of information logged as in files and emails (cebe) - Chg: Use `limit(null)` instead of `limit(-1)` in migration controller to be compatible to more backends (cebe) -- Chg: `yii\web\Request::cookieValidationKey` is now automatically generated by the installation script for the basic and advanced application templates (qiangxue) +- Chg: `yii\web\Request::cookieValidationKey` must be explicitly specified for each application that wants to use cookie validation (qiangxue) - New #3911: Added `yii\behaviors\SluggableBehavior` that fills the specified model attribute with the transliterated and adjusted version to use in URLs (creocoder) - New #4193: Added `yii\filters\Cors` CORS filter to allow Cross Origin Resource Sharing (pgaultier) diff --git a/framework/UPGRADE.md b/framework/UPGRADE.md index e33f11e..df38dda 100644 --- a/framework/UPGRADE.md +++ b/framework/UPGRADE.md @@ -78,6 +78,20 @@ Upgrade from Yii 2.0 Beta `new \yii\caching\TagDependency(['tags' => 'TagName'])`, where `TagName` is similar to the group name that you previously used. +* You must explicitly configure `yii\web\Request::cookieValidationKey` with a secret key. Previously this is done automatically. + To do so, modify your application configuration like the following: + + ```php + return [ + // ... + 'components' => [ + 'request' => [ + 'cookieValidationKey' => 'your secret key here', + ], + ], + ]; + ``` + * `yii\rbac\PhpManager` now stores data in three separate files instead of one. In order to convert old file to new ones save the following code as `convert.php` that should be placed in the same directory your `rbac.php` is in: @@ -130,7 +144,8 @@ new ones save the following code as `convert.php` that should be placed in the s its methods to a new syntax, for example: instead of `yii\helpers\Security::hashData()` use `Yii::$app->getSecurity()->hashData()`. Default encryption and hash parameters has been upgraded. If you need to decrypt/validate data that was encrypted/hashed before, use the following configuration of the 'security' component: - ``` + + ```php return [ 'components' => [ 'security' => [ @@ -145,4 +160,4 @@ new ones save the following code as `convert.php` that should be placed in the s ], // ... ]; - ``` \ No newline at end of file + ``` diff --git a/framework/web/Request.php b/framework/web/Request.php index 4e07a15..316fe80 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -35,8 +35,6 @@ use yii\helpers\StringHelper; * @property array $bodyParams The request parameters given in the request body. * @property string $contentType Request content-type. Null is returned if this information is not available. * This property is read-only. - * @property string $cookieValidationKey The secret key used for cookie validation. If it was not set - * previously, a random key will be generated and used. * @property CookieCollection $cookies The cookie collection. This property is read-only. * @property string $csrfToken The token used to perform CSRF validation. This property is read-only. * @property string $csrfTokenFromHeader The CSRF token sent via [[CSRF_HEADER]] by browser. Null is returned @@ -125,6 +123,10 @@ class Request extends \yii\base\Request */ public $enableCookieValidation = true; /** + * @var string a secret key used for cookie validation. This property must be set if [[enableCookieValidation]] is true. + */ + public $cookieValidationKey; + /** * @var string the name of the POST parameter that is used to indicate if a request is a PUT, PATCH or DELETE * request tunneled through POST. Defaults to '_method'. * @see getMethod() @@ -1180,14 +1182,17 @@ class Request extends \yii\base\Request /** * Converts `$_COOKIE` into an array of [[Cookie]]. * @return array the cookies obtained from request + * @throws InvalidConfigException if [[cookieValidationKey]] is not set when [[enableCookieValidation]] is true */ protected function loadCookies() { $cookies = []; if ($this->enableCookieValidation) { - $key = $this->getCookieValidationKey(); + if ($this->cookieValidationKey == '') { + throw new InvalidConfigException(get_class($this) . '::cookieValidationKey must be configured with a secret key.'); + } foreach ($_COOKIE as $name => $value) { - if (is_string($value) && ($value = Yii::$app->getSecurity()->validateData($value, $key)) !== false) { + if (is_string($value) && ($value = Yii::$app->getSecurity()->validateData($value, $this->cookieValidationKey)) !== false) { $cookies[$name] = new Cookie([ 'name' => $name, 'value' => @unserialize($value), @@ -1208,30 +1213,6 @@ class Request extends \yii\base\Request return $cookies; } - private $_cookieValidationKey; - - /** - * @return string the secret key used for cookie validation. If it was not set previously, - * a random key will be generated and used. - */ - public function getCookieValidationKey() - { - if ($this->_cookieValidationKey === null) { - $this->_cookieValidationKey = Yii::$app->getSecurity()->getSecretKey('cookie.validation.key'); - } - - return $this->_cookieValidationKey; - } - - /** - * Sets the secret key used for cookie validation. - * @param string $value the secret key used for cookie validation. - */ - public function setCookieValidationKey($value) - { - $this->_cookieValidationKey = $value; - } - /** * @var Cookie */ diff --git a/framework/web/Response.php b/framework/web/Response.php index 332175b..adc43a2 100644 --- a/framework/web/Response.php +++ b/framework/web/Response.php @@ -365,7 +365,10 @@ class Response extends \yii\base\Response } $request = Yii::$app->getRequest(); if ($request->enableCookieValidation) { - $validationKey = $request->getCookieValidationKey(); + if ($request->cookieValidationKey == '') { + throw new InvalidConfigException(get_class($request) . '::cookieValidationKey must be configured with a secret key.'); + } + $validationKey = $request->cookieValidationKey; } foreach ($this->getCookies() as $cookie) { $value = $cookie->value;