DEV3 Technologies home

DEV3 Developer Forum

How do I configure PHP sessions securely (HttpOnly, Secure, SameSite)?

PHP helpSolved0 views
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?

#php#sessions#security

0

1 reply

dev3 · Accepted answer

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

  • File based sessions in a shared /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.
  • Sessions lock the file while a request runs, so parallel AJAX requests queue up. Call session_write_close() as soon as you finish writing.
  • Do not store large objects or sensitive data like card numbers in the session.
  • Add an idle timeout by storing last_activity in the session and checking it.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.