diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php index 3c7fee71b..65c2d433f 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php @@ -666,7 +666,7 @@ class ActionsAdmin extends Actions private function setAdminAuthToken(string $sToken) : void { - Utils::SetCookie(static::$AUTH_ADMIN_TOKEN_KEY, $sToken, 0); + Utils::SetCookie(static::$AUTH_ADMIN_TOKEN_KEY, $sToken); } private function getAdminToken() : string diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Api.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Api.php index fc056962f..136052449 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Api.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Api.php @@ -80,7 +80,10 @@ abstract class Api $sSslCapath = static::Config()->Get('ssl', 'capath', ''); Utils::$CookieDefaultPath = static::Config()->Get('labs', 'cookie_default_path', ''); - Utils::$CookieDefaultSecure = !!static::Config()->Get('labs', 'cookie_default_secure', false); + Utils::$CookieSameSite = static::Config()->Get('security', 'cookie_samesite', 'Strict'); + Utils::$CookieSecure = isset($_SERVER['HTTPS']) + || 'None' == Utils::$CookieSameSite + || !!static::Config()->Get('labs', 'cookie_default_secure', false); if (!empty($sSslCafile) || !empty($sSslCapath)) { diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php index 3f0fdfb3b..01ffc1baa 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php @@ -181,7 +181,8 @@ class Application extends \RainLoop\Config\AbstractConfig 'admin_panel_key' => array('admin'), 'content_security_policy' => array(''), 'csp_report' => array(false), - 'encrypt_cipher' => array($sCipher) + 'encrypt_cipher' => array($sCipher), + 'cookie_samesite' => array('Strict', 'Strict, Lax or None') ), 'admin_panel' => array( diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php index fe30d4683..bf3e137ec 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php @@ -634,12 +634,14 @@ class ServiceActions $this->oHttp->ServerNoCache(); $sTo = \trim($_GET['to'] ?? ''); if (!empty($sTo) && \preg_match('/^mailto:/i', $sTo)) { - Utils::SetCookie(Actions::AUTH_MAILTO_TOKEN_KEY, + Utils::SetCookie( + Actions::AUTH_MAILTO_TOKEN_KEY, Utils::EncodeKeyValuesQ(array( 'Time' => \microtime(true), 'MailTo' => 'MailTo', 'To' => $sTo - )), 0); + )) + ); } $this->oActions->Location('./'); return ''; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Utils.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Utils.php index a41f317c4..3b4adf942 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Utils.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Utils.php @@ -4,15 +4,11 @@ namespace RainLoop; class Utils { - /** - * @var string - */ static $CookieDefaultPath = ''; - /** - * @var bool|null - */ - static $CookieDefaultSecure = null; + static $CookieSecure = null; + + static $CookieSameSite = 'Strict'; const /** @@ -119,7 +115,26 @@ class Utils : null; } - public static function SetCookie(string $sName, string $sValue = '', int $iExpire = 0, bool $bHttpOnly = true) + private static function _SetCookie(string $sName, string $sValue, int $iExpire) + { + $sPath = static::$CookieDefaultPath; + $sPath = $sPath && \strlen($sPath) ? $sPath : '/'; +/* + if (\strlen($sValue) > 4000 - \strlen($sPath . $sName)) { + throw new \Exception("Cookie '{$sName}' value too long"); + } +*/ + \setcookie($sName, $sValue, array( + 'expires' => $iExpire, + 'path' => $sPath, +// 'domain' => null, + 'secure' => static::$CookieSecure, + 'httponly' => true, + 'samesite' => static::$CookieSameSite + )); + } + + public static function SetCookie(string $sName, string $sValue = '', int $iExpire = 0) { $sPath = static::$CookieDefaultPath; $sPath = $sPath && \strlen($sPath) ? $sPath : '/'; @@ -133,14 +148,7 @@ class Utils } */ foreach (\str_split($sValue, $iMaxSize) as $i => $sPart) { - \setcookie($i ? "{$sName}~{$i}" : $sName, $sPart, array( - 'expires' => $iExpire, - 'path' => $sPath, -// 'domain' => $sDomain, - 'secure' => isset($_SERVER['HTTPS']) || static::$CookieDefaultSecure, - 'httponly' => $bHttpOnly, - 'samesite' => 'Strict' - )); + static::_SetCookie($i ? "{$sName}~{$i}" : $sName, $sPart, $iExpire); } } @@ -151,14 +159,7 @@ class Utils foreach (\array_keys($_COOKIE) as $sCookieName) { if (\strtok($sCookieName, '~') === $sName) { unset($_COOKIE[$sCookieName]); - \setcookie($sCookieName, '', array( - 'expires' => \time() - 3600 * 24 * 30, - 'path' => $sPath && \strlen($sPath) ? $sPath : '/', -// 'domain' => null, - 'secure' => isset($_SERVER['HTTPS']) || static::$CookieDefaultSecure, - 'httponly' => true, - 'samesite' => 'Strict' - )); + static::_SetCookie($sCookieName, '', \time() - 3600 * 24 * 30); } } }