Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKate Butler <kate@innocraft.com>2019-12-10 02:53:05 +0300
committerThomas Steur <tsteur@users.noreply.github.com>2019-12-10 02:53:05 +0300
commiteec0711a0031d1378793d338ac302b4c3699caac (patch)
tree8b0b981348674786d822accb9986324afd84c7ec
parent89007f29c299d22e7554ebdbf1567ebf60721f32 (diff)
Use appropriate SameSite value for session cookie (#15186)
* Set SameSite=lax for session cookie * Update warning text when Matomo is installed on HTTP * urlencode all session cookie values
-rw-r--r--core/Session.php37
-rw-r--r--core/Session/SessionAuth.php12
-rw-r--r--lang/en.json2
-rw-r--r--libs/Zend/Session.php35
4 files changed, 80 insertions, 6 deletions
diff --git a/core/Session.php b/core/Session.php
index 024c5246d8..683c3e0410 100644
--- a/core/Session.php
+++ b/core/Session.php
@@ -185,4 +185,41 @@ class Session extends Zend_Session
{
return self::$sessionStarted;
}
+
+ /**
+ * Write cookie header. Similar to the native setcookie() function but also supports
+ * the SameSite cookie property.
+ * @param $name
+ * @param $value
+ * @param int $expires
+ * @param string $path
+ * @param string $domain
+ * @param bool $secure
+ * @param bool $httpOnly
+ * @param string $sameSite
+ * @return string
+ */
+ public static function writeCookie($name, $value, $expires = 0, $path = '/', $domain = '/', $secure = false, $httpOnly = false, $sameSite = 'lax')
+ {
+ $headerStr = 'Set-Cookie: ' . rawurlencode($name) . '=' . rawurlencode($value);
+ if ($expires) {
+ $headerStr .= '; expires=' . rawurlencode($expires);
+ }
+ if ($path) {
+ $headerStr .= '; path=' . rawurlencode($path);
+ }
+ if ($domain) {
+ $headerStr .= '; domain=' . rawurlencode($domain);
+ }
+ if ($secure) {
+ $headerStr .= '; secure';
+ }
+ if ($httpOnly) {
+ $headerStr .= '; httponly';
+ }
+ if ($sameSite) {
+ $headerStr .= '; SameSite=' . rawurlencode($sameSite);
+ }
+ return $headerStr;
+ }
}
diff --git a/core/Session/SessionAuth.php b/core/Session/SessionAuth.php
index 1ad0aa26de..2b803b686f 100644
--- a/core/Session/SessionAuth.php
+++ b/core/Session/SessionAuth.php
@@ -187,8 +187,16 @@ class SessionAuth implements Auth
// we update the session cookie to make sure expired session cookies are not available client side...
$sessionCookieLifetime = Config::getInstance()->General['login_cookie_expire'];
- setcookie(session_name(), session_id(), time() + $sessionCookieLifetime, $sessionParams['path'],
- $sessionParams['domain'], $sessionParams['secure'], $sessionParams['httponly']);
+ Session::writeCookie(
+ session_name(),
+ session_id(),
+ time() + $sessionCookieLifetime,
+ $sessionParams['path'],
+ $sessionParams['domain'],
+ $sessionParams['secure'],
+ $sessionParams['httponly'],
+ 'lax'
+ );
// ...and we also update the expiration time stored server side so we can prevent expired sessions from being reused
$sessionFingerprint->updateSessionExpirationTime();
diff --git a/lang/en.json b/lang/en.json
index 17f920373c..c3c715ea23 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -111,7 +111,7 @@
"ConfigFileIsNotWritable": "The Matomo configuration file %1$s is not writable, some of your changes might not be saved. %2$s Please change permissions of the config file to make it writable.",
"Continue": "Continue",
"ContinueToPiwik": "Continue to Matomo",
- "CurrentlyUsingUnsecureHttp": "You are currently using Matomo over unsecure HTTP, which can be risky. We recommend you set up Matomo to use SSL (HTTPS) for improved security.",
+ "CurrentlyUsingUnsecureHttp": "You are currently using Matomo over unsecure HTTP. This can make your Matomo vulnerable to security exploits. You may also be in breach of privacy laws, as some features including opt-out cookies will not work. We recommend you set up Matomo to use SSL (HTTPS) for improved security.",
"CreatedByUser": "created by %s",
"CurrentMonth": "Current Month",
"CurrentWeek": "Current Week",
diff --git a/libs/Zend/Session.php b/libs/Zend/Session.php
index 73668507aa..793f76b8ed 100644
--- a/libs/Zend/Session.php
+++ b/libs/Zend/Session.php
@@ -313,11 +313,38 @@ class Zend_Session extends Zend_Session_Abstract
} else {
if (!self::$_unitTestEnabled) {
session_regenerate_id(true);
+ self::rewriteSessionCookieWithSameSiteDirective();
}
self::$_regenerateIdState = 1;
}
}
+ /**
+ * Check if there is a Set-Cookie header present - if so, overwrite it with
+ * a similar header which also includes a SameSite directive. This workaround
+ * is needed because the SameSite property on the session cookie is not supported
+ * by PHP until 7.3.
+ */
+ private static function rewriteSessionCookieWithSameSiteDirective()
+ {
+ $headers = headers_list();
+ $cookieHeader = '';
+ foreach ($headers as $header) {
+ if (strpos($header, 'Set-Cookie: ' . \Piwik\Session::SESSION_NAME) === 0) {
+ $cookieHeader = $header;
+ break;
+ }
+ }
+
+ if (! $cookieHeader) {
+ return;
+ }
+
+ if (stripos($cookieHeader, 'SameSite') === false) {
+ $cookieHeader .= '; SameSite=Lax';
+ header($cookieHeader);
+ }
+ }
/**
* rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of
@@ -763,14 +790,16 @@ class Zend_Session extends Zend_Session_Abstract
if (isset($_COOKIE[session_name()])) {
$cookie_params = session_get_cookie_params();
- setcookie(
+ \Piwik\Session::writeCookie(
session_name(),
false,
315554400, // strtotime('1980-01-01'),
$cookie_params['path'],
$cookie_params['domain'],
- $cookie_params['secure']
- );
+ $cookie_params['secure'],
+ false,
+ 'lax'
+ );
}
}