mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-14 14:28:27 +08:00
Fixes #17353: Added sameSite
support for yii\web\Cookie
and yii\web\Session::cookieParams
This commit is contained in:

committed by
Alexander Makarov

parent
b638cc4a4e
commit
1ed6ec1e5c
@ -332,11 +332,6 @@ examples, the [[yii\web\Cookie]] class also defines other properties to fully re
|
||||
information, such as [[yii\web\Cookie::domain|domain]], [[yii\web\Cookie::expire|expire]]. You may configure these
|
||||
properties as needed to prepare a cookie and then add it to the response's cookie collection.
|
||||
|
||||
> Note: For better security, the default value of [[yii\web\Cookie::httpOnly]] is set to `true`. This helps mitigate
|
||||
the risk of a client-side script accessing the protected cookie (if the browser supports it). You may read
|
||||
the [httpOnly wiki article](https://www.owasp.org/index.php/HttpOnly) for more details.
|
||||
|
||||
|
||||
### Cookie Validation <span id="cookie-validation"></span>
|
||||
|
||||
When you are reading and sending cookies through the `request` and `response` components as shown in the last
|
||||
@ -369,3 +364,34 @@ return [
|
||||
|
||||
> Info: [[yii\web\Request::cookieValidationKey|cookieValidationKey]] is critical to your application's security.
|
||||
It should only be known to people you trust. Do not store it in the version control system.
|
||||
|
||||
## Security settings
|
||||
|
||||
Both [[yii\web\Cookie]] and [[yii\web\Session]] support the following security flags:
|
||||
|
||||
### httpOnly
|
||||
|
||||
For better security, the default value of [[yii\web\Cookie::httpOnly]] and the 'httponly' parameter of
|
||||
[[yii\web\Session::cookieParams]] is set to `true`. This helps mitigate the risk of a client-side script accessing
|
||||
the protected cookie (if the browser supports it).
|
||||
You may read the [HttpOnly wiki article](https://www.owasp.org/index.php/HttpOnly) for more details.
|
||||
|
||||
### secure
|
||||
The purpose of the secure flag is to prevent cookies from being send in clear text. If the browser supports the
|
||||
secure flag it will only include the cookie when the request is sent over a secure (TLS) connection.
|
||||
You may read the [SecureFlag wiki article](https://www.owasp.org/index.php/SecureFlag) for more details.
|
||||
|
||||
### sameSite
|
||||
Starting with Yii 2.0.21 the [[yii\web\Cookie::sameSite]] setting is supported. It requires PHP version 7.3.0 or higher.
|
||||
The purpose of the `sameSite` setting is to prevent CSRF (Cross-Site Request Forgery) attacks.
|
||||
If the browser supports the `sameSite` setting it will only include the cookie according to the specified policy ('Lax' or 'Strict').
|
||||
You may read the [SameSite wiki article](https://www.owasp.org/index.php/SameSite) for more details.
|
||||
For better security, an exception will be thrown if `sameSite` is used with an unsupported version of PHP.
|
||||
To use this feature across different PHP versions check the version first. E.g.
|
||||
```php
|
||||
[
|
||||
'sameSite' => PHP_VERSION_ID >= 70300 ? yii\web\Cookie::SAME_SITE_LAX : null,
|
||||
]
|
||||
```
|
||||
> Note: Since not all browsers support the `sameSite` setting yet, it is still strongly recommended to also include
|
||||
[additional CSRF protection](security-best-practices.md#avoiding-csrf).
|
||||
|
@ -253,9 +253,14 @@ class ContactAction extends Action
|
||||
|
||||
> Warning: Disabling CSRF will allow any site to send POST requests to your site. It is important to implement extra validation such as checking an IP address or a secret token in this case.
|
||||
|
||||
> Note: Since version 2.0.21 Yii supports the `sameSite` cookie setting (requires PHP version 7.3.0 or higher).
|
||||
Setting the `sameSite` cookie setting does not make the above obsolete since not all browsers support the setting yet.
|
||||
See the [Sessions and Cookies sameSite option](runtime-sessions-cookies.md#samesite) for more information.
|
||||
|
||||
Further reading on the topic:
|
||||
|
||||
- <https://www.owasp.org/index.php/CSRF>
|
||||
- <https://www.owasp.org/index.php/SameSite>
|
||||
|
||||
|
||||
Avoiding file exposure
|
||||
@ -301,6 +306,10 @@ provided by the H5BP project:
|
||||
- [IIS](https://github.com/h5bp/server-configs-iis).
|
||||
- [Lighttpd](https://github.com/h5bp/server-configs-lighttpd).
|
||||
|
||||
> Note: When TLS is configured it is recommended that (session) cookies are send over TLS exclusively.
|
||||
This is achieved by setting the `secure` flag for sessions and/or cookies.
|
||||
See the [Sessions and Cookies secure flag](runtime-sessions-cookies.md#secure) for more information.
|
||||
|
||||
|
||||
Secure Server configuration
|
||||
---------------------------
|
||||
|
@ -7,6 +7,7 @@ Yii Framework 2 Change Log
|
||||
- Bug #17341: Fixed error from yii.activeForm.js in strict mode (mikehaertl)
|
||||
- Enh #17345: Improved performance of `yii\db\Connection::quoteColumnName()` (brandonkelly)
|
||||
- Enh #17348: Improved performance of `yii\db\Connection::quoteTableName()` (brandonkelly)
|
||||
- Enh #17353: Added `sameSite` support for `yii\web\Cookie` and `yii\web\Session::cookieParams` (rhertogh)
|
||||
|
||||
|
||||
2.0.20 June 04, 2019
|
||||
|
@ -17,6 +17,23 @@ namespace yii\web;
|
||||
*/
|
||||
class Cookie extends \yii\base\BaseObject
|
||||
{
|
||||
/**
|
||||
* SameSite policy Lax will prevent the cookie from being sent by the browser in all cross-site browsing context
|
||||
* during CSRF-prone request methods (e.g. POST, PUT, PATCH etc).
|
||||
* E.g. a POST request from https://otherdomain.com to https://yourdomain.com will not include the cookie, however a GET request will.
|
||||
* When a user follows a link from https://otherdomain.com to https://yourdomain.com it will include the cookie
|
||||
* @see $sameSite
|
||||
*/
|
||||
const SAME_SITE_LAX = 'Lax';
|
||||
/**
|
||||
* SameSite policy Strict will prevent the cookie from being sent by the browser in all cross-site browsing context
|
||||
* regardless of the request method and even when following a regular link.
|
||||
* E.g. a GET request from https://otherdomain.com to https://yourdomain.com or a user following a link from
|
||||
* https://otherdomain.com to https://yourdomain.com will not include the cookie.
|
||||
* @see $sameSite
|
||||
*/
|
||||
const SAME_SITE_STRICT = 'Strict';
|
||||
|
||||
/**
|
||||
* @var string name of the cookie
|
||||
*/
|
||||
@ -48,6 +65,19 @@ class Cookie extends \yii\base\BaseObject
|
||||
* such as JavaScript, which can effectively help to reduce identity theft through XSS attacks.
|
||||
*/
|
||||
public $httpOnly = true;
|
||||
/**
|
||||
* @var string SameSite prevents the browser from sending this cookie along with cross-site requests.
|
||||
* Please note that this feature is only supported since PHP 7.3.0
|
||||
* For better security, an exception will be thrown if `sameSite` is set while using an unsupported version of PHP.
|
||||
* To use this feature across different PHP versions check the version first. E.g.
|
||||
* ```php
|
||||
* $cookie->sameSite = PHP_VERSION_ID >= 70300 ? yii\web\Cookie::SAME_SITE_LAX : null,
|
||||
* ```
|
||||
* See https://www.owasp.org/index.php/SameSite for more information about sameSite.
|
||||
*
|
||||
* @since 2.0.21
|
||||
*/
|
||||
public $sameSite;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -401,7 +401,21 @@ class Response extends \yii\base\Response
|
||||
if ($cookie->expire != 1 && isset($validationKey)) {
|
||||
$value = Yii::$app->getSecurity()->hashData(serialize([$cookie->name, $value]), $validationKey);
|
||||
}
|
||||
setcookie($cookie->name, $value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->secure, $cookie->httpOnly);
|
||||
if (PHP_VERSION_ID >= 70300) {
|
||||
setcookie($cookie->name, $value, [
|
||||
'expires' => $cookie->expire,
|
||||
'path' => $cookie->path,
|
||||
'domain' => $cookie->domain,
|
||||
'secure' => $cookie->secure,
|
||||
'httpOnly' => $cookie->httpOnly,
|
||||
'sameSite' => !empty($cookie->sameSite) ? $cookie->sameSite : null,
|
||||
]);
|
||||
} else {
|
||||
if (!is_null($cookie->sameSite)) {
|
||||
throw new InvalidConfigException(get_class($cookie) . '::sameSite is not supported by PHP versions < 7.3.0 (set it to null in this environment)');
|
||||
}
|
||||
setcookie($cookie->name, $value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->secure, $cookie->httpOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,6 +367,16 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
||||
* The cookie parameters passed to this method will be merged with the result
|
||||
* of `session_get_cookie_params()`.
|
||||
* @param array $value cookie parameters, valid keys include: `lifetime`, `path`, `domain`, `secure` and `httponly`.
|
||||
* Starting with Yii 2.0.21 `sameSite` is also supported. It requires PHP version 7.3.0 or higher.
|
||||
* For securtiy, an exception will be thrown if `sameSite` is set while using an unsupported version of PHP.
|
||||
* To use this feature across different PHP versions check the version first. E.g.
|
||||
* ```php
|
||||
* [
|
||||
* 'sameSite' => PHP_VERSION_ID >= 70300 ? yii\web\Cookie::SAME_SITE_LAX : null,
|
||||
* ]
|
||||
* ```
|
||||
* See https://www.owasp.org/index.php/SameSite for more information about `sameSite`.
|
||||
*
|
||||
* @throws InvalidArgumentException if the parameters are incomplete.
|
||||
* @see https://secure.php.net/manual/en/function.session-set-cookie-params.php
|
||||
*/
|
||||
@ -385,7 +395,15 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
||||
{
|
||||
$data = $this->getCookieParams();
|
||||
if (isset($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly'])) {
|
||||
session_set_cookie_params($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly']);
|
||||
if (PHP_VERSION_ID >= 70300) {
|
||||
session_set_cookie_params($data);
|
||||
} else {
|
||||
if (!empty($data['sameSite'])) {
|
||||
throw new InvalidConfigException('sameSite cookie is not supported by PHP versions < 7.3.0 (set it to null in this environment)');
|
||||
}
|
||||
session_set_cookie_params($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly']);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new InvalidArgumentException('Please make sure cookieParams contains these elements: lifetime, path, domain, secure and httponly.');
|
||||
}
|
||||
|
Reference in New Issue
Block a user