Table of Contents
5. Secure Session Practices — Predictable, Boundaried, and Safe
Once identity is established, the next question is:
how do we maintain it safely?
A session is a temporary identity.
It represents a user between requests
— nothing more, nothing less.
Security comes from treating the session as a boundary, not a convenience.
A session should be predictable, explicit, and difficult to misuse.
Modern PHP gives you the tools;
the discipline comes from how you use them.
This page introduces
the mental model for
safe session handling in PHP.
1. Regenerate the Session ID After Login
The most important rule is:
→ Regenerate the session ID immediately after authentication.
This prevents session fixation, where an attacker forces a victim to use a known session ID.
In PHP:
session_regenerate_id(true);
This creates a new session with a new ID and deletes the old one.
A session should never carry pre‑login identity into post‑login state.
2. Use Strict Cookie Flags
The session cookie is the key to the user’s identity.
Protect it with strict boundaries:
- HttpOnly → JavaScript cannot read it
- Secure → only sent over HTTPS
- SameSite=Strict → prevents cross‑site request leakage
- Path=/ → avoid unnecessary exposure
In PHP:
session_set_cookie_params([ 'httponly' => true, 'secure' => true, 'samesite' => 'Strict', ]);
A session cookie should be treated like a password.
3. Keep Session Data Small and Intentional
A session is not a storage container.
It is a state boundary.
Avoid storing:
- user objects
- permissions
- large arrays
- cached data
- anything that can drift out of sync
Prefer storing:
- user ID
- minimal flags
- temporary state
Everything else should be fetched fresh
or cached elsewhere.
Small sessions are predictable sessions.
4. Never Store Sensitive Data in the Session
Do not store:
- passwords
- tokens
- secrets
- raw personal data
- anything that would be dangerous if leaked
Sessions can be:
- logged
- dumped
- serialized
- exposed through misconfiguration
Treat the session as a place for identifiers, not secrets.
5. Destroy Sessions Cleanly on Logout
A proper logout:
- clears session data
- regenerates the session ID
- invalidates the cookie
In PHP:
$_SESSION = []; session_destroy(); setcookie(session_name(), '', time() - 3600);
Logout should be a boundary reset,
not a partial cleanup.
6. Avoid Long‑Lived Sessions
Long sessions increase risk.
Prefer:
- short lifetimes
- sliding expiration
- explicit renewal
- inactivity timeouts
A session should reflect active identity,
not historical identity.
7. Do Not Rely on Session IDs in URLs
Never use:
- ?session_id=…
- URL‑based session propagation
- query‑string identity
This exposes the session to:
- logs
- referrer headers
- browser history
- link sharing
Always use cookies for session identity.
8. Validate Session State on Every Request
A session is not a guarantee of identity
— it is a claim.
Validate:
- user still exists
- account is still active
- permissions have not changed
- session data is still consistent
A session should not outlive the truth of the system.
9. Treat Sessions as a Security Boundary
A session is not just a convenience.
It is a boundary between:
- anonymous and authenticated
- past and present
- one user and another
Security comes from respecting that boundary.
Summary
Secure session handling in PHP is about clarity and boundaries.
A secure system:
- regenerates session IDs after login
- uses strict cookie flags
- keeps session data small
- avoids storing sensitive information
- destroys sessions cleanly
- avoids long‑lived sessions
- never uses URL‑based session IDs
- validates session state continuously
A session is temporary identity.
Treat it with care.
This page describes secure defaults and common practices in modern PHP. It is not a complete security guide, and it does not replace formal audits or framework‑specific documentation. These principles are consistent enough to be useful, but security always requires context, judgment, and ongoing review.
