From 0df3a3c51c60977c4c9ef929de11cce79f77d2e2 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 28 Jan 2026 08:21:25 +0100 Subject: Rewrite setcookie using new syntax (#8447) Follow-up of https://github.com/FreshRSS/FreshRSS/pull/2630 now that we have PHP 7.3+ (even PHP 8.1+). * The new syntax natively supports `samesite`, and also avoids the need of re-setting all parameters. * Use automatic path instead of own function `getCookieDir()`. Follow-up of https://github.com/FreshRSS/FreshRSS/pull/8446 * Sanitize lifetime of session cookies from PHP ini to avoid likely invalid/misunderstood values --- lib/Minz/Session.php | 58 ++++++++++++++++++++++------------------------------ p/.htaccess | 1 - 2 files changed, 24 insertions(+), 35 deletions(-) diff --git a/lib/Minz/Session.php b/lib/Minz/Session.php index aafbbbde8..6cb26ce71 100644 --- a/lib/Minz/Session.php +++ b/lib/Minz/Session.php @@ -30,7 +30,7 @@ class Minz_Session { } /** - * Initialize the session, with a name + * Initialize and start the session, with a name * The session name is used as the name for cookies and URLs (i.e. PHPSESSID). * It should contain only alphanumeric characters; it should be short and descriptive * If the volatile parameter is true, then no cookie and not session storage are used. @@ -43,19 +43,24 @@ class Minz_Session { return; } - $cookie = session_get_cookie_params(); - self::keepCookie($cookie['lifetime']); + $params = session_get_cookie_params(); + // Sanitize lifetime of session cookies from PHP ini `session.cookie_lifetime` (default 0) + $params['lifetime'] = ($params['lifetime'] <= 0 || $params['lifetime'] > 86400) ? 0 : $params['lifetime']; + $params['path'] = ''; // Current directory + $params['domain'] = ''; // Current domain + $params['secure'] = Minz_Request::isHttps(); + $params['httponly'] = true; + $params['samesite'] = 'Lax'; + session_set_cookie_params($params); - // start session session_name($name); - //When using cookies (default value), session_stars() sends HTTP headers + // When using cookies (default value), session_start() sends HTTP headers session_start(); session_write_close(); - //Use cookie only the first time the session is started to avoid resending HTTP headers + // Use cookie only the first time the session is started to avoid resending HTTP headers ini_set('session.use_cookies', '0'); } - /** * Allows you to retrieve a session variable * @param string $p the parameter to retrieve @@ -175,27 +180,6 @@ class Minz_Session { } } - public static function getCookieDir(): string { - // Get the script_name (e.g. /p/i/index.php) and keep only the path. - $cookie_dir = ''; - if (!empty($_SERVER['HTTP_X_FORWARDED_PREFIX']) && is_string($_SERVER['HTTP_X_FORWARDED_PREFIX'])) { - $cookie_dir .= rtrim($_SERVER['HTTP_X_FORWARDED_PREFIX'], '/ '); - } - $cookie_dir .= empty($_SERVER['REQUEST_URI']) || !is_string($_SERVER['REQUEST_URI']) ? '/' : $_SERVER['REQUEST_URI']; - if (substr($cookie_dir, -1) !== '/') { - $cookie_dir = dirname($cookie_dir) . '/'; - } - return $cookie_dir; - } - - /** - * Specifies the lifetime of the cookies - * @param int $l the lifetime - */ - public static function keepCookie(int $l): void { - session_set_cookie_params($l, self::getCookieDir(), '', Minz_Request::isHttps(), true); - } - /** * Regenerate a session id. */ @@ -214,21 +198,27 @@ class Minz_Session { Minz_Error::error(500); return; } - $lifetime = session_get_cookie_params()['lifetime']; - $expire = $lifetime > 0 ? time() + $lifetime : 0; - setcookie($name, $newId, $expire, self::getCookieDir(), '', Minz_Request::isHttps(), true); + $params = session_get_cookie_params(); + $params['expires'] = $params['lifetime'] > 0 ? time() + $params['lifetime'] : 0; + unset($params['lifetime']); + setcookie($name, $newId, $params); } public static function deleteLongTermCookie(string $name): void { - setcookie($name, '', 1, '', '', Minz_Request::isHttps(), true); + $params = session_get_cookie_params(); + $params['expires'] = 1; + unset($params['lifetime']); + setcookie($name, '', $params); } public static function setLongTermCookie(string $name, string $value, int $expire): void { - setcookie($name, $value, $expire, '', '', Minz_Request::isHttps(), true); + $params = session_get_cookie_params(); + $params['expires'] = $expire; + unset($params['lifetime']); + setcookie($name, $value, $params); } public static function getLongTermCookie(string $name): string { return is_string($_COOKIE[$name] ?? null) ? $_COOKIE[$name] : ''; } - } diff --git a/p/.htaccess b/p/.htaccess index 06790616b..f6216a439 100644 --- a/p/.htaccess +++ b/p/.htaccess @@ -44,7 +44,6 @@ AddDefaultCharset UTF-8 Header merge Cache-Control "immutable" - Header edit Set-Cookie ^(.*)$ "$1; SameSite=Lax" # Provide the true IP address of the connection (e.g. last proxy), even when using mod_remoteip -- cgit v1.2.3