Under attack? Get incident response help

Secure development

Session management checks for cookies, timeouts and logout

A checklist for testing web sessions: ID strength, cookie attributes, rotation at login, timeouts and server-side logout, with curl commands for key tests.

Also in:TürkçeDeutschFrançaisEspañolItalianoPolskiNederlandsEesti

Illustration: Session management checks for cookies, timeouts and logout

Once a user has logged in, the session ID is temporarily equivalent to the strongest authentication method the application used, whether that was a password, a one-time code, a client certificate, a smartcard or a fingerprint. If an attacker can guess, capture or fix that ID, they are the user, and the login form never comes into it. Testing sessions therefore means testing the ID, the cookie that carries it, and what the server does with it at login, after idle time and at logout.

This checklist follows the OWASP Session Management Cheat Sheet and RFC 6265, the cookie specification.

The session ID itself

Start with how the ID is made. The cheat sheet requires at least 64 bits of entropy from a cryptographically secure random number generator. At that size it estimates roughly 585 years to guess a valid ID, assuming 10,000 guesses per second and 100,000 valid sessions at once. If you generate your own IDs rather than using the framework's, it recommends at least 128 bits and a unique value for each session.

Look for fixed or predictable parts. A 16-character hexadecimal ID with half of it fixed has only 32 bits of entropy, which is not enough. The value should also mean nothing to the client: no user ID, role or email inside it. Keep that state on the server.

Check the name too. Defaults such as PHPSESSID, JSESSIONID, CFID/CFTOKEN and ASP.NET_SessionId tell an attacker which stack you run. The cheat sheet suggests a generic name such as id.

Never accept the ID in a URL. URL-borne IDs leak through links, logs, browser history, bookmarks, the Referer header and search engines, and they make fixation easier.

If read access to your session store is in your threat model, raw tokens are a risk. The cheat sheet describes a split design: the cookie carries an identifier and a secret verifier, and the server stores the identifier plus the SHA-256 hash of the verifier, compared in constant time. The identifier alone is never accepted.

RFC 6265 defines these attributes for a Set-Cookie header: Expires, Max-Age, Domain, Path, Secure and HttpOnly.

  • Secure marks the cookie for secure connections. The RFC warns that it gives no integrity against an active network attacker, so do not treat it as protection against one.
  • HttpOnly belongs on every session cookie. Confirm the flag in the browser developer tools.
  • Domain and Path define scope. Keep both no wider than the application needs.
  • Expires and Max-Age tell the browser how long to keep the cookie. Do not use them as your timeout.

Review the rest of your response headers with our security headers tool.

Login, timeouts and logout

A session ID that the browser held before login and keeps after it is what fixation attacks rely on. Issue a fresh ID when the user authenticates, so the earlier one stops being valid.

Timeouts need two limits. An idle timeout ends sessions nobody is using. An absolute timeout ends sessions that stay busy forever, which limits how long a stolen ID stays useful. Write the numbers down, make them shorter for administration and payments, and enforce them on the server by checking the stored session record, not the cookie's expiry date.

Logout must destroy the server-side session. Clearing the cookie in the browser is not enough, because the identifier is the credential: anyone who copied it earlier can still send it. After logout, the old ID should map to nothing. The cheat sheet also has a section on web content caching and Clear-Site-Data, which is worth reading for what the browser keeps after logout.

Use the framework's built-in session handling where you can. The cheat sheet notes that these implementations have had vulnerabilities, so run the latest version and review the defaults.

What to test

  1. Capture the cookie before and after login. The first request must actually set a session cookie, so check that before.txt is not empty. Keep the credentials in a file (creds.txt containing user=test&pass=...) so they stay out of shell history. The two IDs must differ.

curl -i -c before.txt https://app.example/login curl -i -b before.txt -c after.txt -d @creds.txt https://app.example/login

  1. Log out with the authenticated cookie, then replay the old value, taken from the last column of after.txt. It must be rejected. If logout is a POST, add -d '' to the first command.

curl -i -b after.txt https://app.example/logout curl -i -b 'id=VALUE_FROM_AFTER_TXT' https://app.example/account

  1. Log in, stay idle past the idle timeout, then send a request. It must require authentication again.
  2. Keep a session active past the absolute timeout. It must still end.
  3. Inspect Set-Cookie on the login response for Secure, HttpOnly, and a Domain and Path no wider than needed.
  4. Collect a few hundred IDs and compare them. Fixed segments and sequential values are findings. Check the cookie name against the framework defaults above.
  5. Search the application, logs and links for session IDs in URLs.

Report findings against OWASP ASVS with the version attached: v5.0.0-<chapter>.<section>.<requirement>. ASVS 5.0.0 was published on 30 May 2025 and its requirements come as CSV. Add a column to your test sheet with the identifier for each test, so a failed test reads as a finding that cites its requirement.

Where to start

  1. Run tests 1 and 2 against staging first: the ID comparison before and after login, then the logout replay.
  2. Capture the Set-Cookie header for your session cookie and fix the attributes that are missing or too broad.
  3. Check how IDs are generated. If you built your own generator, move to the framework's, or confirm it uses a secure random source with at least 128 bits.
  4. Write down the idle and absolute timeouts, enforce them server-side, and add tests that fail if someone removes them.
  5. Make logout delete the server-side session record, and add the replay tests to your regression suite.

How we can help

Penetration testing

We attack your networks, applications and people the way a real adversary would, then show you how to close each gap.

Security headers scanner

Grade a website’s HTTP security headers, cookies and TLS certificate, with a fix for every finding.

Contact us
AngelForce team

Written by the AngelForce team: security consultants with CEH, LPT Master and CISA certifications who test, monitor and defend systems for organisations across Europe.

Written with AI assistance from public sources listed below, and reviewed by the AngelForce team before publication.

Sources

  1. cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
  2. www.rfc-editor.org/rfc/rfc6265.html
  3. asvs.owasp.org/

Articles about Secure development

Tell us what you need to protect

Describe your environment and what you want to achieve. We will reply by email.

Contact us
info@angelforce.eu +372 5705 2044

AngelForce OÜ · Tallinn, Estonia