From 11cd2b086eafb96fe6b418c4ab7e15817fe54c20 Mon Sep 17 00:00:00 2001 From: randoum Date: Thu, 12 Nov 2020 22:40:39 +0200 Subject: [PATCH] Allow to set SameSite from system.yaml (#3063) * Update system.yaml * Update SessionServiceProvider.php * Update Session.php * Update system.yaml --- system/blueprints/config/system.yaml | 6 ++++ system/config/system.yaml | 1 + .../Common/Service/SessionServiceProvider.php | 4 ++- system/src/Grav/Framework/Session/Session.php | 32 +++++++++++++------ 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index de390e7fb..573fe2012 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -1343,6 +1343,12 @@ form: label: PLUGIN_ADMIN.SESSION_PATH help: PLUGIN_ADMIN.SESSION_PATH_HELP + session.samesite: + type: text + size: small + label: PLUGIN_ADMIN.SESSION_SAMESITE + help: PLUGIN_ADMIN.SESSION_SAMESITE_HELP + session.split: type: toggle label: PLUGIN_ADMIN.SESSION_SPLIT diff --git a/system/config/system.yaml b/system/config/system.yaml index 56f0a2e07..c8d8b04bc 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -168,6 +168,7 @@ session: uniqueness: path # Should sessions be `path` based or `security.salt` based secure: false # Set session secure. If true, indicates that communication for this cookie must be over an encrypted transmission. Enable this only on sites that run exclusively on HTTPS httponly: true # Set session HTTP only. If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed. + samesite: # Set session SameSite. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite split: true # Sessions should be independent between site and plugins (such as admin) path: diff --git a/system/src/Grav/Common/Service/SessionServiceProvider.php b/system/src/Grav/Common/Service/SessionServiceProvider.php index 2d4dffbc8..300d5e0fe 100644 --- a/system/src/Grav/Common/Service/SessionServiceProvider.php +++ b/system/src/Grav/Common/Service/SessionServiceProvider.php @@ -44,6 +44,7 @@ class SessionServiceProvider implements ServiceProviderInterface $cookie_httponly = (bool)$config->get('system.session.httponly', true); $cookie_lifetime = (int)$config->get('system.session.timeout', 1800); $cookie_path = $config->get('system.session.path'); + $cookie_samesite = $config->get('system.session.samesite'); if (null === $cookie_path) { $cookie_path = '/' . trim(Uri::filterPath($uri->rootUrl(false)), '/'); } @@ -95,7 +96,8 @@ class SessionServiceProvider implements ServiceProviderInterface 'cookie_path' => $cookie_path, 'cookie_domain' => $cookie_domain, 'cookie_secure' => $cookie_secure, - 'cookie_httponly' => $cookie_httponly + 'cookie_httponly' => $cookie_httponly, + 'cookie_samesite' => $cookie_samesite ] + (array) $config->get('system.session.options'); $session = new Session($options); diff --git a/system/src/Grav/Framework/Session/Session.php b/system/src/Grav/Framework/Session/Session.php index 8f7af7e82..20c41c04a 100644 --- a/system/src/Grav/Framework/Session/Session.php +++ b/system/src/Grav/Framework/Session/Session.php @@ -140,6 +140,7 @@ class Session implements SessionInterface 'use_strict_mode' => true, 'use_cookies' => true, 'use_only_cookies' => true, + 'cookie_samesite' => true, 'referer_check' => true, 'cache_limiter' => true, 'cache_expire' => true, @@ -243,14 +244,19 @@ class Session implements SessionInterface if ($sessionExists) { $params = session_get_cookie_params(); + $cookie_options = array ( + 'expires' => time() + $params['lifetime'], + 'path' => $params['path'], + 'domain' => $params['domain'], + 'secure' => $params['secure'], + 'httponly' => $params['httponly'], + 'samesite' => $params['samesite'] + ); + setcookie( $sessionName, session_id(), - time() + $params['lifetime'], - $params['path'], - $params['domain'], - $params['secure'], - $params['httponly'] + $cookie_options ); } @@ -309,14 +315,20 @@ class Session implements SessionInterface public function invalidate() { $params = session_get_cookie_params(); + + $cookie_options = array ( + 'expires' => time() - 42000, + 'path' => $params['path'], + 'domain' => $params['domain'], + 'secure' => $params['secure'], + 'httponly' => $params['httponly'], + 'samesite' => $params['samesite'] + ); + setcookie( session_name(), '', - time() - 42000, - $params['path'], - $params['domain'], - $params['secure'], - $params['httponly'] + $cookie_options ); if ($this->isSessionStarted()) {