A session is a sequence of requests and responses from one browser to one or more sites. Session management authenticates the user once so that all subsequent requests are tied to that user.
The server assigns a token to identify the session. Anonymous tokens can be elevated to logged-in tokens after authentication.
Three main options; each has tradeoffs. The best approach is a combination tailored to the application.
Set-Cookie: SessionToken=fduhye63sfdb - sent with
every request.
Downside: enables CSRF
(browser sends cookie even when user didn't intend the request).
https://site.com/checkout?SessionToken=kh7y3b - every
request carries token.
Downside: leaks via
Referer header or if user posts URL publicly.
<input type="hidden" name="sessionid"
value="kh7y3b">
- every user action must submit a form or token is lost.
Use a combination of all three - cookie, URL embed, and hidden field - depending on application needs. No single method is perfect.
Token size is a concern. Large tokens bloat requests. Cookies have size limits. Tokens expire, but revocation mechanisms should exist.
The Referer header tells the server which page the user
came from. Useful for analytics, but creates a privacy and security
problem.
Referer leaks the URL - including any session token in the query
string - to third-party sites when the user clicks a link. If the
previous page had ?SessionToken=xyz, that token is sent
to the linked site.
Referer suppression -
don't send Referer when linking out. HTM<a rel="noreferrer" href="https://example.com">
Web sites must provide logout for both functionality (switch users) and security (prevent abuse of abandoned sessions).
Many sites do 1 but not 2. The server never invalidates the token. An attacker who stole the token (e.g., via cleartext HTTP at a café) can continue using it after the user logs out. Especially risky when sites use HTTPS for login but fall back to HTTP afterward.
The attacker steals a legitimate session token and uses it to impersonate the victim. Can be passive (sniff silently) or active (disconnect user; social engineering).
User logs in, gets counter value. Attacker can guess other counter values and view other users' sessions. Never use sequential IDs.
Weak cryptographic protection exposes the secret key from a few cookies. Attacker recovers key, derives counter, hijacks sessions.
Use
unpredictable tokens.
Rely on framework APIs: ASP, Tomcat
generateSessionId(), Rails. Example:
Token = MD5(current_time, random_nonce)
Login over HTTPS, then fallback to HTTP. Token sent in cleartext. Network attacker at wireless café (e.g., Firesheep) intercepts. Also: MITM on SSL handshake.
Cross-Site Scripting steals token (e.g., via
document.cookie). Amplified by poor logout - if
server doesn't invalidate, stolen token works indefinitely.
Embedding machine-specific data (IP, User-Agent) in the session ID seems appealing but has problems:
Bad: DHCP changes IP; user gets locked out of own session.
Bad: User-Agent is easily stolen or guessed by attacker.
Best approach: unpredictable server-generated token. No reliable client binding.
Attacker sets the user's session token, then tricks the user into logging in with that token. The attacker's token gets elevated to logged-in; attacker hijacks the session.
https://site.com/login?SessionToken=attacker_token
For cookie tokens: use XSS to set the cookie value before victim logs in.
When elevating user from anonymous to logged-in: always issue a new session token. After login, the token changes to a value unknown to the attacker. The attacker's original token is not elevated.
Best practices for cookie-based session management.
Session integrity for web applications - binding sessions to origins.