cookies and sessions
Cookies and Sessions
Learn how web applications maintain state across stateless HTTP requests using browser cookies, server-side sessions, secure identifiers, expiration policies and session lifecycle controls.
Introduction
HTTP is a stateless application protocol. Each request can be processed independently, and the protocol does not automatically remember that two requests came from the same signed-in user.
Web applications frequently need continuity across requests for:
- User authentication
- Shopping carts
- Language and display preferences
- Multi-step forms
- Authorization context
- Temporary workflow state
- Security and fraud-prevention controls
Cookies and sessions provide mechanisms for maintaining this continuity. A cookie is stored by the user agent and conditionally returned with later requests. A server-side session stores application state on the server and commonly uses a cookie containing an opaque session identifier to associate requests with that state.
Core distinction: A cookie is client-side state managed by the browser according to cookie rules. A session is an application concept representing continuity across requests. A server-side session commonly uses a cookie only as a reference to state stored on the server.
In your System Design curriculum, Cookies and Sessions is Topic 3.6 under Networking and Web Request Lifecycle. It follows HTTP/1.1, HTTP/2 and HTTP/3 and precedes WebSockets, Server-Sent Events and long polling.
Prerequisites
| # | Prerequisite | Why It Is Needed |
|---|---|---|
| 1 | HTTP requests and responses | Cookies are transferred through HTTP request and response fields. |
| 2 | TLS and HTTPS | Authentication cookies must be protected while travelling across the network. |
| 3 | HTTP methods and status codes | Login, logout and session-protected operations use normal HTTP semantics. |
| 4 | Authentication and authorization basics | A session can identify a user, but the application must still authorize operations. |
| 5 | Databases and caches | Server-side session state is commonly stored in a database, cache or distributed session store. |
| 6 | Basic PHP | The implementation examples use PHP session and cookie functions. |
Why HTTP Needs State Management
Request 1:
POST /login
Username and password submitted
Request 2:
GET /dashboard
Question:
How does the server know that Request 2
belongs to the user authenticated in Request 1?
The application needs a value that connects later requests to an authenticated session or another state record.
What Is a Cookie?
A cookie is a name-value pair and associated attributes stored by a user
agent. A server can send a cookie using the
Set-Cookie response field.
HTTP/1.1 200 OK
Set-Cookie: session_id=opaque-random-value; Path=/; Secure; HttpOnly; SameSite=Lax
Content-Type: application/json
{"status":"authenticated"}
On a later eligible request, the browser returns the cookie using the
Cookie request field.
GET /dashboard HTTP/1.1
Host: app.example.com
Cookie: session_id=opaque-random-value
Cookie Lifecycle
Server response
|
| Set-Cookie
v
Browser evaluates cookie attributes
|
v
Browser stores eligible cookie
|
v
Later request matches cookie scope
|
| Cookie
v
Server receives cookie value
Whether the browser sends a cookie depends on attributes such as domain, path, security mode, same-site policy and expiration.
Cookie Attributes
| Attribute | Purpose |
|---|---|
| Name and value | Store the cookie's application-defined data |
Domain |
Defines the host scope available to the cookie |
Path |
Limits requests by URL path |
Expires |
Defines an absolute expiration date |
Max-Age |
Defines the cookie lifetime in seconds |
Secure |
Restricts cookie transmission to secure connections |
HttpOnly |
Prevents access through applicable client-side script APIs |
SameSite |
Controls whether the cookie is included in cross-site request contexts |
Cookie Domain Scope
Cookie domain rules determine which hosts can receive a cookie.
Host-only Cookie
Set-Cookie: session_id=random-value; Path=/; Secure; HttpOnly
When the Domain attribute is omitted, the cookie is restricted
to the host that set it according to the browser's cookie rules.
Domain Cookie
Set-Cookie: preference=compact; Domain=example.com; Path=/
A domain-scoped cookie can be available to eligible subdomains. Session cookies should not receive broader domain scope than the application requires.
Scope rule: Prefer the narrowest cookie domain and path that satisfy the application requirement. Broader scope increases the number of requests and hosts to which the cookie can be exposed.
Cookie Path Scope
Set-Cookie: admin_session=random-value; Path=/admin; Secure; HttpOnly
The path attribute limits the requests to which the browser includes the cookie.
Cookie path:
/admin
Eligible request paths:
/admin
/admin/
/admin/users
Not an eligible path match:
/courses
Path scope is a browser cookie-delivery control. It should not be treated as an application authorization boundary.
Session and Persistent Cookies
| Cookie Type | General Behaviour |
|---|---|
| Session cookie | Does not contain an explicit persistent lifetime and is retained according to user-agent session behaviour |
| Persistent cookie | Contains an expiration policy through Expires or Max-Age |
Persistent Cookie Example
Set-Cookie: theme=dark; Max-Age=2592000; Path=/; Secure; SameSite=Lax
A persistent lifetime should reflect the cookie's purpose. Authentication state normally requires stricter lifetime controls than a visual preference.
Secure Attribute
Set-Cookie: session_id=random-value; Secure
The Secure attribute restricts cookie transmission to secure
connections.
Set-Cookie: session_id=random-value; Path=/
Set-Cookie: session_id=random-value; Path=/; Secure; HttpOnly; SameSite=Lax
The exact SameSite policy must be selected according to the application's navigation, federation and cross-site requirements.
HttpOnly Attribute
Set-Cookie: session_id=random-value; HttpOnly
The HttpOnly attribute prevents eligible client-side scripts
from reading the cookie through applicable cookie APIs.
HttpOnly helps limit session-token theft through injected script, but it does not:
- Prevent every cross-site scripting attack
- Stop malicious script from issuing requests through the user's browser
- Replace output encoding and content security controls
- Protect a token exposed elsewhere
- Replace server-side authorization
SameSite Attribute
The SameSite attribute controls cookie inclusion in cross-site
request contexts.
| Value | General Behaviour | Application Consideration |
|---|---|---|
Strict |
Uses the most restrictive same-site delivery policy | Can interfere with legitimate navigation from another site |
Lax |
Allows selected top-level navigation while restricting other cross-site contexts | Often balances usability and cross-site request protection |
None |
Allows eligible cross-site cookie delivery | Requires Secure and a deliberate cross-site security design |
CSRF rule: SameSite is an important defence, but the complete design can also require anti-CSRF tokens, origin validation, safe HTTP method usage, reauthentication and transaction confirmation.
What Is a Session?
A session represents application state associated with a sequence of related requests.
A session can contain:
- Authenticated user identifier
- Authentication time
- Authorization context
- Session creation and last-activity times
- Security-level or authentication-method information
- Temporary workflow state
- CSRF-related state
- Session status
Sensitive state should normally remain on the server. The browser receives an opaque identifier that does not expose the session's internal content.
Server-side Session Flow
User submits credentials
|
v
Server verifies credentials
|
v
Server creates session record
|
v
Server generates random session identifier
|
v
Browser receives identifier in secure cookie
|
v
Browser sends cookie on later eligible request
|
v
Server loads and validates session
|
v
Application authorizes requested operation
Example Session Record
| Field | Purpose |
|---|---|
| Session identifier hash | Locates the session without storing the raw bearer token where the design avoids it |
| User identifier | Associates the session with an authenticated account |
| Created time | Records when the session began |
| Last activity | Supports idle-expiration policy |
| Absolute expiry | Places a maximum lifetime on the session |
| Status | Identifies active, revoked or expired state |
| Security metadata | Supports risk and policy decisions |
Cookies vs Sessions
| Area | Cookie | Server-side Session |
|---|---|---|
| Storage location | User agent | Server-side session store |
| Common content | Opaque session ID, preference or compact state | User and workflow state |
| Sent with requests | Yes, when cookie scope and policy match | Normally only the session identifier is sent |
| Client modification | The client controls stored cookie data and can attempt modification | Session data remains under server control |
| Server storage | Not required for simple cookie state | Required unless sessions are represented through another self-contained design |
| Revocation | Can be difficult for self-contained state without server tracking | The server can mark or remove the session record |
| Scalability concern | Request size and browser limits | Session-store capacity, availability and cleanup |
Session Identifier
A session identifier is commonly a bearer credential. A request presenting a valid identifier can be treated as belonging to the associated session.
A secure session identifier should be:
- Generated by a cryptographically secure random generator
- Unpredictable
- Sufficiently large
- Meaningless outside the server-side lookup
- Protected during transport and storage
- Rotated at important authentication boundaries
- Invalidated according to the session lifecycle
session_id = user_id + current_timestamp
session_id = cryptographically secure random bytes
The identifier contains no:
- User ID
- Email address
- Role
- Timestamp
- Sequential counter
Session ID Rotation
The application should generate a new session identifier when the session's security context changes.
Common rotation points include:
- Successful login
- Privilege elevation
- Administrative-role activation
- Reauthentication
- Account recovery
- Another policy-defined change in trust level
Anonymous session ID
|
| Successful authentication
v
Invalidate or detach old identifier
|
v
Generate new authenticated session ID
|
v
Return updated session cookie
Rotation helps prevent an identifier established before authentication from remaining the authenticated session identifier.
Session Fixation
Session fixation occurs when an attacker causes a victim to use a session identifier already known to the attacker and the application retains that identifier after authentication.
Attacker obtains or chooses session ID
|
v
Victim uses the same session ID
|
v
Victim authenticates
|
v
Application does not rotate session ID
|
v
Attacker reuses known authenticated session ID
Defences include:
- Generating identifiers only through trusted server logic
- Rotating the identifier after authentication
- Rejecting session identifiers supplied through unsupported channels
- Invalidating the previous identifier after rotation
Session Hijacking
Session hijacking occurs when an attacker obtains and successfully reuses a valid session credential.
Possible causes include:
- Network exposure without HTTPS
- Cross-site scripting
- Session IDs recorded in logs
- Session IDs included in URLs
- Insecure browser storage
- Malware or endpoint compromise
- Weak identifier generation
- Overly broad cookie scope
- Long session lifetimes
Session Hijacking Controls
- Use HTTPS throughout the authenticated experience.
- Mark authentication cookies as Secure and HttpOnly.
- Choose an intentional SameSite policy.
- Do not place session identifiers in URLs.
- Prevent sensitive token logging.
- Rotate identifiers after authentication changes.
- Apply idle and absolute expiration.
- Support immediate server-side revocation.
- Use reauthentication for sensitive actions.
Cross-site Request Forgery
Cross-site request forgery, commonly abbreviated as CSRF, takes advantage of a browser automatically attaching authentication cookies to an eligible request initiated from another site.
User is authenticated to trusted.example
|
v
User visits another website
|
v
Other website triggers request to trusted.example
|
v
Browser may attach eligible session cookie
|
v
Trusted application receives authenticated request
CSRF defences can include:
- SameSite cookie policy
- Anti-CSRF tokens
- Origin or Referer validation
- Custom request fields for applicable APIs
- Correct use of safe and unsafe HTTP methods
- Reauthentication or confirmation for sensitive operations
Anti-CSRF Token Pattern
Server creates session
|
v
Server generates CSRF token
|
v
Token is included in trusted form or application state
|
v
Client submits token with state-changing request
|
v
Server verifies token against session context
|
+--> Valid: continue
|
+--> Missing or invalid: reject
The CSRF token should be unpredictable, associated with the appropriate security context and validated on applicable state-changing requests.
Session Expiration
Sessions should not remain valid indefinitely.
| Expiration Type | Meaning |
|---|---|
| Idle timeout | Session expires after a defined period without qualifying activity |
| Absolute timeout | Session expires after a maximum period regardless of activity |
| Event-driven revocation | Session becomes invalid after logout, password reset, account disablement or another security event |
Session created
|
+--> Idle timer updated by qualifying activity
|
+--> Absolute expiry remains fixed
|
+--> Security event can revoke immediately
The client-side cookie lifetime and server-side session lifetime should be designed together. A browser retaining a cookie does not make an expired or revoked server-side session valid.
Logout
A secure logout process should invalidate the server-side session and instruct the browser to remove the associated cookie.
User requests logout
|
v
Server validates current session
|
v
Server revokes or deletes session record
|
v
Server expires browser cookie
|
v
Later use of old session ID is rejected
Cookie Deletion Example
Set-Cookie: session_id=; Max-Age=0; Path=/; Secure; HttpOnly; SameSite=Lax
Cookie deletion should use path and domain scope compatible with the original cookie. Deleting only the client cookie without invalidating the server session can leave a reusable server-side credential.
Session Storage Options
| Storage | Benefit | Consideration |
|---|---|---|
| Application memory | Simple and fast for one process | Sessions can be lost during restart and are not automatically shared across instances |
| Local files | Simple server-side persistence | Shared access, cleanup and multi-instance use require careful design |
| Relational database | Durable centralized state and transactional controls | Database load and cleanup must be managed |
| Distributed cache | Fast shared access across application instances | Availability, eviction, persistence and expiry behaviour must be understood |
| Dedicated session service | Centralized lifecycle and policy management | Adds a network dependency and operational complexity |
Sessions in a Scaled Application
Browser
|
| Session cookie
v
Load Balancer
|
+--> Application Instance A --+
| |
+--> Application Instance B --+--> Shared Session Store
| |
+--> Application Instance C --+
A shared session store allows any authorized application instance to load the same session.
The design should address:
- Session-store availability
- Read and write latency
- Expiration and cleanup
- Consistency requirements
- Maximum session size
- Failure and retry behaviour
- Encryption and access control
- Monitoring and capacity
Sticky Sessions
Sticky sessions route a client to the same application instance for subsequent requests according to a load-balancer affinity mechanism.
User A -> Instance 1
User A -> Instance 1
User A -> Instance 1
User B -> Instance 2
User B -> Instance 2
Sticky sessions can simplify local session access but can create:
- Uneven traffic distribution
- Session loss after instance failure
- More complex deployment and scaling behaviour
- Dependence on affinity configuration
- Reduced flexibility when draining instances
Affinity does not replace durable or shared state when sessions must survive instance changes.
Stateful and Self-contained Sessions
| Design | Description |
|---|---|
| Server-side stateful session | The client presents an opaque identifier and the server loads session state |
| Self-contained token | The client presents signed or otherwise protected claims that can be validated without a normal session lookup |
A self-contained token is not automatically safer or more scalable. It creates design questions around:
- Revocation
- Token lifetime
- Key rotation
- Claim freshness
- Token audience
- Replay
- Storage location
- Token size
Terminology rule: A cookie is a browser storage and transport mechanism. A token is an application credential format. A token can be carried in a cookie, an authorization field or another supported channel.
Secure PHP Session Configuration
Configure session-cookie behaviour before starting the PHP session.
<?php
declare(strict_types=1);
$isHttps =
isset($_SERVER['HTTPS'])
&& $_SERVER['HTTPS'] !== 'off';
if (!$isHttps) {
http_response_code(400);
exit(
'HTTPS is required.'
);
}
session_name(
'app_session'
);
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
The appropriate SameSite value depends on the application's navigation, federation, embedded-content and cross-site requirements.
PHP Login Session Example
<?php
declare(strict_types=1);
require_once 'session_bootstrap.php';
function authenticateUser(
string $username,
string $password
): ?array {
/*
* Replace with a parameterized database query
* and password_verify() against a securely
* stored password hash.
*/
return null;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
exit(
'Method not allowed.'
);
}
$username =
trim(
$_POST['username'] ?? ''
);
$password =
$_POST['password'] ?? '';
$user =
authenticateUser(
$username,
$password
);
if ($user === null) {
http_response_code(401);
exit(
'Invalid credentials.'
);
}
if (!session_regenerate_id(true)) {
http_response_code(500);
exit(
'Unable to establish session.'
);
}
$_SESSION['user_id'] =
(int)$user['id'];
$_SESSION['authenticated_at'] =
time();
$_SESSION['last_activity_at'] =
time();
http_response_code(204);
The session identifier is regenerated after authentication so the authenticated session does not retain a pre-authentication identifier.
Validate a PHP Session
<?php
declare(strict_types=1);
require_once 'session_bootstrap.php';
const IDLE_TIMEOUT_SECONDS = 1800;
const ABSOLUTE_TIMEOUT_SECONDS = 28800;
function revokeCurrentSession(): void
{
$_SESSION = [];
if (ini_get(
'session.use_cookies'
)) {
$parameters =
session_get_cookie_params();
setcookie(
session_name(),
'',
[
'expires' => time() - 3600,
'path' => $parameters['path'],
'domain' => $parameters['domain'],
'secure' => $parameters['secure'],
'httponly' => $parameters['httponly'],
'samesite' => $parameters['samesite']
]
);
}
session_destroy();
}
$userId =
$_SESSION['user_id'] ?? null;
$authenticatedAt =
$_SESSION['authenticated_at'] ?? null;
$lastActivityAt =
$_SESSION['last_activity_at'] ?? null;
if (!is_int($userId) ||
!is_int($authenticatedAt) ||
!is_int($lastActivityAt)) {
revokeCurrentSession();
http_response_code(401);
exit(
'Authentication required.'
);
}
$currentTime =
time();
$idleExpired =
$currentTime - $lastActivityAt
> IDLE_TIMEOUT_SECONDS;
$absoluteExpired =
$currentTime - $authenticatedAt
> ABSOLUTE_TIMEOUT_SECONDS;
if ($idleExpired ||
$absoluteExpired) {
revokeCurrentSession();
http_response_code(401);
exit(
'Session expired.'
);
}
$_SESSION['last_activity_at'] =
$currentTime;
The timeout values are illustrative. Production values must follow the application's security, usability and organizational requirements.
PHP Logout Example
<?php
declare(strict_types=1);
require_once 'session_bootstrap.php';
$_SESSION = [];
if (ini_get(
'session.use_cookies'
)) {
$parameters =
session_get_cookie_params();
setcookie(
session_name(),
'',
[
'expires' => time() - 3600,
'path' => $parameters['path'],
'domain' => $parameters['domain'],
'secure' => $parameters['secure'],
'httponly' => $parameters['httponly'],
'samesite' => $parameters['samesite']
]
);
}
session_destroy();
http_response_code(204);
A distributed server-side session implementation must also invalidate the corresponding session record in the shared session store.
Example Session Table
CREATE TABLE user_sessions
(
session_id_hash CHAR(64) PRIMARY KEY,
user_id BIGINT NOT NULL,
created_at DATETIME NOT NULL,
last_activity_at DATETIME NOT NULL,
expires_at DATETIME NOT NULL,
revoked_at DATETIME NULL,
authentication_level VARCHAR(30) NOT NULL,
INDEX ix_user_sessions_user_id (user_id),
INDEX ix_user_sessions_expires_at (expires_at)
);
This is an illustrative structure. The final schema should reflect the selected database, token-hashing method, retention policy, query patterns and privacy requirements.
Session Cleanup
Expired and revoked session records should be removed or archived according to an explicit retention policy.
DELETE FROM user_sessions
WHERE
expires_at < CURRENT_TIMESTAMP
OR revoked_at IS NOT NULL;
Cleanup can run through a controlled scheduled process. Large deletes may require batching to avoid extended locking, log growth or load spikes.
Sensitive Operations
A valid session does not always provide sufficient assurance for every action.
Sensitive actions can require:
- Recent reauthentication
- Multi-factor authentication
- Transaction confirmation
- Current authorization evaluation
- CSRF validation
- Risk-based controls
- Audit logging
Valid session
|
v
Sensitive operation requested
|
v
Check recent authentication
|
+--> Sufficient:
| continue authorization
|
+--> Insufficient:
require step-up authentication
Privacy Considerations
Cookies can be used for necessary application functions or for tracking user activity.
Privacy-aware design should include:
- Collecting only necessary data
- Using clear cookie purposes
- Applying appropriate retention periods
- Avoiding sensitive personal data in cookie values
- Restricting third-party sharing
- Providing required notice and controls
- Following applicable organizational and legal requirements
Important Session Metrics
| Metric | What It Helps Explain |
|---|---|
| Active session count | Current session-store demand |
| Session creation rate | Login and anonymous-session workload |
| Session validation latency | Cost of loading and checking session state |
| Expired session rate | Timeout and cleanup behaviour |
| Revoked session rate | Logout and security-event activity |
| Session-store errors | Availability and connectivity problems |
| Authentication failure rate | Invalid login attempts and authentication problems |
| CSRF rejection rate | Missing or invalid anti-CSRF validation |
| Session rotation failures | Problems at authentication-boundary transitions |
| Cookie rejection symptoms | Scope, SameSite, Secure or browser-policy incompatibility |
Inspect Cookies with curl
Save Received Cookies
curl -c cookies.txt -i https://example.com/login
Send Stored Cookies
curl -b cookies.txt -i https://example.com/dashboard
Verbose Cookie Exchange
curl -v -c cookies.txt -b cookies.txt https://example.com/
Cookie files can contain authentication credentials. Store and handle them only in approved test environments, restrict access and remove them after use.
Browser Inspection
Browser developer tools can help inspect:
- Cookies stored for the current site
- Cookie domain and path
- Secure and HttpOnly status
- SameSite policy
- Expiration
- Set-Cookie response fields
- Cookie request fields
- Blocked-cookie reasons
Diagnostic caution: Do not copy real authentication cookie values into tickets, chat messages, screenshots or logs. A valid session identifier can function as a bearer credential.
Troubleshooting Workflow
- Confirm the exact hostname, scheme and request path.
- Inspect the server's
Set-Cookieresponse. - Verify that the browser accepted and stored the cookie.
- Inspect Domain, Path, Secure, HttpOnly and SameSite attributes.
- Verify that the cookie is included in the expected later request.
- Check whether the session record exists.
- Check idle, absolute and event-driven expiration.
- Check whether the session ID was rotated unexpectedly.
- Inspect proxy and load-balancer behaviour.
- Verify authorization after successful session validation.
- Check server clock consistency.
- Compare the failing browser flow with a working request.
Scenario: Cookie Is Stored but Not Sent
Investigate:
- Request scheme and the Secure attribute
- Request hostname and cookie domain
- Request path and cookie path
- SameSite policy and request context
- Cookie expiration
- Browser privacy policy
- Cross-origin request credentials configuration
- Whether the cookie was replaced by another cookie with the same name
Scenario: User Is Logged Out Unexpectedly
Investigate:
- Idle-session expiration
- Absolute-session expiration
- Session-store eviction
- Application restart with memory-only sessions
- Load balancing across instances without shared state
- Cookie expiration or rejection
- Session identifier regeneration
- Password or account-security events
- Server clock differences
Scenario: Login Redirect Loop
Request protected page
|
v
Application finds no valid session
|
v
Redirect to login
|
v
Login succeeds and sets cookie
|
v
Redirect to protected page
|
v
Cookie is missing or session cannot be loaded
|
v
Redirect to login again
Investigate:
- Whether
Set-Cookiewas returned - Whether the browser accepted the cookie
- Domain and path mismatch
- Secure cookie used over an insecure request
- SameSite behaviour during an external identity flow
- Session-store consistency
- Proxy hostname and scheme forwarding
- Redirect target hostname changes
Common Cookies and Sessions Mistakes
Storing Passwords in Cookies
Passwords and raw authentication secrets should not be stored in browser cookies.
Using Predictable Session IDs
Sequential identifiers, timestamps and user IDs do not provide secure session-token unpredictability.
Missing Secure Attribute
Authentication cookies should not be transmitted through an insecure HTTP connection.
Missing HttpOnly Attribute
Session identifiers that do not require script access should be protected against direct access through applicable client-side APIs.
Choosing SameSite Without Testing the Login Flow
Federated login, payment redirects and embedded applications can require carefully designed cross-site behaviour.
Not Rotating the Session ID after Login
Keeping a pre-authentication identifier can expose the application to session-fixation risks.
Deleting Only the Browser Cookie at Logout
The corresponding server session should also become invalid.
Using Only an Idle Timeout
Continuous activity can keep the session alive indefinitely without an absolute lifetime.
Putting Session IDs in URLs
URLs can be exposed through history, logs, analytics, bookmarks and referrer information.
Storing Large Objects in Sessions
Large session records increase storage, serialization and network cost between application instances and the session store.
Assuming Authentication Means Authorization
A valid session identifies an authenticated context. Each protected operation still requires authorization.
Logging Complete Cookie Headers
Logs can expose reusable session credentials and should follow explicit redaction rules.
Recommended Test Cases
| Test | Expected Evidence |
|---|---|
| Successful login | A new session is created and a secure session cookie is returned |
| Session fixation test | The identifier changes after authentication |
| Cookie scope test | The cookie is sent only to intended hosts and paths |
| HTTP transport test | A Secure session cookie is not sent through an insecure connection |
| Client-side script test | An HttpOnly session cookie cannot be read through the applicable script API |
| Cross-site request test | Cookie and CSRF behaviour follows the application's policy |
| Idle timeout | The inactive session expires after the configured idle period |
| Absolute timeout | The session expires after its maximum lifetime despite activity |
| Logout | The server session is invalid and the browser cookie is removed |
| Old-token replay | A rotated or revoked identifier is rejected |
| Application-instance failure | The session follows the documented shared-state or affinity behaviour |
| Session-store outage | The application fails safely without bypassing authentication |
Cookies and Sessions Best Practices
Recommended Practices
- Use cryptographically secure, opaque session identifiers.
- Keep sensitive session state on the server.
- Use HTTPS throughout authenticated flows.
- Mark authentication cookies as Secure and HttpOnly.
- Select an intentional SameSite policy.
- Use the narrowest practical cookie domain and path.
- Do not place session identifiers in URLs.
- Rotate the session identifier after authentication and privilege changes.
- Apply idle and absolute expiration.
- Invalidate sessions after logout and security events.
- Use anti-CSRF controls for applicable state-changing operations.
- Perform authorization on every protected operation.
- Require recent authentication for sensitive actions.
- Limit session-record size.
- Protect the session store with least-privilege access.
- Redact cookies and tokens from logs.
- Monitor session creation, expiry, revocation and validation failures.
- Test browser, proxy and identity-provider flows end to end.
Practice Exercise
Build and test a secure server-side login session for a PHP web application.
Requirements
- Require HTTPS for authenticated pages.
- Generate the session identifier through PHP's secure session mechanism.
- Use Secure, HttpOnly and an intentional SameSite policy.
- Regenerate the identifier after successful login.
- Store only the required authenticated state in the session.
- Apply an idle timeout.
- Apply an absolute timeout.
- Protect state-changing forms with anti-CSRF validation.
- Authorize every protected operation.
- Invalidate the server-side session during logout.
- Remove the browser cookie during logout.
- Reject an old identifier after rotation or logout.
- Redact session identifiers from logs.
- Test behaviour across several application instances.
Session Design Template
Cookie name:
<Application-specific name>
Cookie scope:
<Host and path>
Secure:
<Required>
HttpOnly:
<Required when script access is unnecessary>
SameSite:
<Strict, Lax or None with justification>
Session identifier:
<Opaque cryptographically secure random value>
Server-side store:
<Database, distributed cache or dedicated service>
Idle timeout:
<Policy-defined duration>
Absolute timeout:
<Policy-defined duration>
Rotation events:
<Login, privilege change, reauthentication and others>
Revocation events:
<Logout, password reset, account disablement and others>
CSRF protection:
<Token, origin validation and SameSite policy>
Authorization:
<Per-operation access evaluation>
Monitoring:
<Failures, expiration, revocation and store health>
Frequently Asked Questions
What is a cookie?
A cookie is a name-value pair and associated attributes stored by a user agent and conditionally returned with eligible HTTP requests.
What is a session?
A session is application state associated with a sequence of related requests.
What is the difference between a cookie and a session?
A cookie is stored by the browser. A server-side session is stored by the application and is commonly referenced by an identifier in a cookie.
What does Secure do?
The Secure attribute restricts cookie transmission to secure connections.
What does HttpOnly do?
HttpOnly prevents applicable client-side script APIs from reading the cookie.
What does SameSite do?
SameSite controls whether the browser sends the cookie in cross-site request contexts.
Should session data be stored in a cookie?
Sensitive or frequently changing session state is normally better kept under server control, with only an opaque identifier stored in the cookie.
Why regenerate the session ID after login?
Regeneration prevents a pre-authentication identifier from remaining the identifier of the authenticated session.
Does SameSite completely prevent CSRF?
No. SameSite is one layer. The application can also require anti-CSRF tokens, origin checks, method controls and reauthentication.
Should logout only delete the cookie?
No. The server-side session should also be revoked or deleted so the old credential cannot be reused.
Can sessions work across several application servers?
Yes. Applications can use shared session storage, a dedicated session service or another architecture that makes state available to authorized instances.
What comes after cookies and sessions?
The next topic is WebSockets, Server-Sent Events and long polling.
Key Takeaway
Cookies allow browsers and servers to maintain continuity across stateless HTTP requests. A secure server-side session normally stores sensitive state on the server and places only an opaque random identifier in a narrowly scoped Secure, HttpOnly cookie with an intentional SameSite policy. Rotate the identifier after authentication changes, apply idle and absolute expiration, protect state-changing requests against CSRF, revoke sessions after logout and security events, and perform authorization on every protected operation.