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;