Fixes #17353: Added sameSite support for yii\web\Cookie and yii\web\Session::cookieParams

This commit is contained in:
rhertogh
2019-06-10 23:33:36 +02:00
committed by Alexander Makarov
parent b638cc4a4e
commit 1ed6ec1e5c
6 changed files with 105 additions and 7 deletions

View File

@ -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

View File

@ -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;
/**

View File

@ -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);
}
}
}

View File

@ -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.');
}