mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 13:58:55 +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
@ -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