dev3 ·
My login uses $_SESSION but a security review says the session cookie is missing flags and sessions are vulnerable to fixation. How do I configure PHP sessions properly?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
My login uses $_SESSION but a security review says the session cookie is missing flags and sessions are vulnerable to fixation. How do I configure PHP sessions properly?
Set strict session options before session_start().
session_set_cookie_params([
'lifetime' => 0, // browser session
'path' => '/',
'domain' => '', // current host only
'secure' => true, // HTTPS only
'httponly' => true, // not readable by JavaScript
'samesite' => 'Lax', // or 'Strict'
]);
ini_set('session.use_strict_mode', '1');
ini_set('session.use_only_cookies', '1');
session_start();
Or in php.ini:
session.use_strict_mode = 1
session.use_only_cookies = 1
session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Lax
session.gc_maxlifetime = 1440
What each protects against
HttpOnly: an XSS bug cannot read the session id with document.cookie.Secure: the cookie is never sent over plain HTTP. If you are behind a TLS-terminating proxy and PHP thinks the request is HTTP, the cookie may not be set, so configure HTTPS detection ($_SERVER['HTTPS'] or trusted X-Forwarded-Proto handling).SameSite: blocks the cookie on cross-site POSTs, reducing CSRF.use_strict_mode: PHP rejects session ids it did not create, so an attacker cannot make you adopt a chosen id (session fixation).Regenerate the id on privilege change
session_regenerate_id(true); // right after login, and after role changes
$_SESSION['user_id'] = $user['id'];
Logout properly
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$p = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
}
session_destroy();
Pitfalls
/tmp can be read by other accounts on shared hosting; set session.save_path to a private directory, or use a database or Redis handler.session_write_close() as soon as you finish writing.last_activity in the session and checking it.