Start with the session journey
A session cookie often carries an opaque identifier that lets a server recognize a signed-in customer. The identifier can cross many requests during a booking, order lookup, or account update. Before selecting flags, list every host that actually needs it: for example the public site, a separate checkout host, an account host, and any identity provider return path. Also record which requests originate from an external site. The owner can then see whether a proposed cookie policy serves the real journey or merely copies a framework default. A policy should be tested against the complete route, including return from payment or sign-in.
The cookie is only one layer of session protection. Server side expiration, invalidation, authorization checks, and protection against forged actions remain necessary. OWASP explicitly warns that deleting a browser cookie alone does not invalidate a stolen session identifier, and it treats SameSite as defence in depth rather than a replacement for anti-CSRF controls. This guide concentrates on what the browser sends and what page scripts can read. Keep the broader account lifecycle in its own test plan, especially for logout and recovery, so a green cookie inspection does not become a false security signoff.
Write down the business consequence of a session failure. A stricter setting that silently logs customers out after returning from checkout may produce duplicate attempts or abandoned bookings. A loose setting that sends the identifier to unnecessary hosts broadens exposure. The appropriate choice is the narrowest setting that still supports the documented path, plus a test for any exception. Do not solve a broken return flow by making every cookie broadly available before diagnosing whether the flow actually needs that cookie at all.
Keep the identifier on the protected channel
Set Secure on a session identifier and serve the entire authenticated journey over HTTPS. MDN and OWASP both explain that Secure limits transmission to encrypted requests; it is not a substitute for HTTPS throughout the session. Check the response that sets the cookie and the requests that later carry it, including a redirect from an old HTTP link. A login page using HTTPS is insufficient if an authenticated page or subresource falls back to HTTP. Test in the deployed environment because a reverse proxy may terminate TLS before the application decides which attributes to issue.
Set HttpOnly when page JavaScript has no legitimate need to read the session identifier. It prevents access through document.cookie, which narrows a common route for stealing the identifier after a script injection. It does not stop a malicious script from making requests that automatically include the cookie, so input handling and authorization remain essential. If a frontend says it needs the raw identifier to decide what to display, challenge the design: a server endpoint can return the permitted account information without exposing the session secret. Test that normal page functions still work with HttpOnly enabled.
A practical inspection begins with the response header, not with a screenshot of the browser cookie panel alone. Confirm the intended cookie is issued with Secure and HttpOnly, then use browser developer tools to see which subsequent requests include it. Avoid copying a live identifier into tickets or shared screenshots; redact values while retaining the name and attributes needed for review. Inspect a newly issued cookie after login as well as any refreshed cookie, since a refresh route can accidentally omit flags that the original login response supplied.
Choose SameSite from the actual navigation
SameSite controls whether a browser includes a cookie with cross-site requests. Strict excludes cross-site requests; Lax permits certain top-level cross-site navigations using safe methods; None allows cross-site use but requires Secure. These are browser rules, not labels for a company’s marketing preference. MDN documents the attribute and OWASP recommends explicitly setting Strict or Lax for session cookies rather than relying on browser defaults. Start with Strict where the customer journey permits it, then test links, identity returns, and checkout returns before deciding whether Lax is required.
Imagine a customer begins on a comparison site and follows a link to an existing account page. With Strict, the first cross-site navigation may not carry the session cookie, so the customer can appear signed out until another same-site navigation. With Lax, a qualifying top-level safe navigation can carry it. That difference may affect continuity but does not justify choosing None for every session. If an embedded cross-site context genuinely requires a cookie, document the exact use, browser behavior, and separate security controls; do not weaken the main account cookie merely to satisfy an unrelated widget.
SameSite is also easy to misunderstand during a payment or single sign-on flow. The cross-site return may use a method or browser context that a chosen value does not cover. Rather than guessing, follow the actual redirect chain in a test browser and record the request method, top-level versus embedded context, and whether the cookie is sent. Complete the final account or booking action after return, because a cookie may appear on one request yet be absent when the server needs it. Keep a recovery path if an external provider changes its return behavior.
Limit which hosts can receive the cookie
A host-only cookie is issued without a Domain attribute. A cookie with Domain set to a parent domain can also be sent to matching subdomains, enlarging the set of systems that receive the identifier. MDN and OWASP both describe this scope. For a small business with a marketing site, customer portal, and old campaign subdomain, sharing one login cookie across all of them is rarely a justified default. List the actual hosts that need the session; where possible, keep the main account identifier on its own host and use supported server-side handoffs for other services.
The __Host- prefix provides a browser-enforced constraint: Secure, Path=/, and no Domain attribute are required. It can help prevent a sibling subdomain from setting a same-named broad cookie. It is suitable when the session belongs to one host and the application can use a root path. It is not appropriate if the same cookie really must be shared between subdomains. A naming prefix cannot replace server validation, but it turns a desired scope rule into something the browser can check rather than a comment that can be forgotten during a later release.
Path narrows when a cookie is sent by URL path, but it is not a strong security boundary between applications on the same host. A separate application may still be able to set or influence cookies under the host. Use path to reduce unnecessary transmission, not as the only isolation between an admin area and a customer area. When adopting __Host-, accept its Path=/ requirement and rely on host separation and server authorization for meaningful isolation. Review legacy cookies with similar names because browser selection of duplicate names can confuse application parsing.
Test the settings as a customer journey
Create a compact matrix covering first login, page refresh, external link return, payment or identity return, account update, session expiry, and logout. For each step, record the host, request context, cookie attributes, whether the cookie travels, and expected account state. Test a second browser profile to show that the result is tied to the correct session. The owner should be able to point to both a protected identifier and an uninterrupted legitimate flow. If a third-party integration truly requires an exception, keep its purpose and expiry under review.
For a worked release example, suppose booking runs on account.example and a brochure runs on www.example. The team sets the account identifier as a host-only __Host- cookie with Secure and HttpOnly, then tries Strict. The brochure link causes an unwanted apparent logout on the first navigation, while the booking flow otherwise works. The team tests whether Lax preserves the intended return and keeps the cookie host-only; it does not add Domain=example merely because the brochure exists. This is an illustrative decision exercise, not an observed result for any real site.
Approve the change only when both sides of the decision are evidenced. Inspect live-like response headers and browser requests for the security properties, and complete the user journeys that depend on the cookie. Record any deviation from the preferred setting with a specific reason and a compensating check. Revisit the matrix when a new subdomain, payment route, identity service, or framework version appears. The purpose is a maintainable boundary: staff can explain where the identifier goes, why it goes there, and what fails safely if it is absent.
Expiry deserves a separate test from browser closure. A cookie with Max-Age or Expires can persist on the device; a cookie without them is commonly called a session cookie, yet browser session restore can preserve it after a window closes. The server must still enforce its own lifetime and reject an expired identifier. Test an idle account, a long booking form, and a returning browser, then compare what the customer sees with the intended timeout policy. A convenience choice to remember a customer should be explicit and should not quietly make every authenticated session long lived.
A migration can leave an old cookie beside the new one. Inventory existing names, Domain and Path values before switching to a host-only prefix; otherwise the server may read the wrong identifier or a customer may appear signed into one page and out of another. Test a browser profile with the previous release cookie as well as a clean profile. Define how the old cookie is expired using the matching scope, and verify the server rejects the old session when its policy requires that. A clean installation test alone will miss this transition.
Before you proceed
- Secure and HttpOnly appear on every issued session identifier.
- SameSite is tested through real external return paths.
- Domain, Path and any prefix match the hosts that truly need the session.


