A server-side session associates an opaque browser token with server-managed state. The browser sends the token back in a Cookie request header; the service looks it up instead of accepting a user ID or role asserted by the client. In these fixtures, the session store and clock are explicit function arguments, so expiration and revocation can be tested without waiting or accessing a network.
The store contains synthetic token strings, user IDs, expiration instants, revocation flags and synchronizer CSRF tokens. These predictable values are test data, not an example token-generation scheme. In a real application use a maintained framework's session handling, cryptographically secure token generation, rotation after authentication or privilege changes, protected transport and server-side invalidation. This lesson builds none of those systems.
A session is usable only while now < expires_at and it is not revoked. At equality it has expired. The build returns the user ID for a permitted request and None for a denied one. Unknown tokens, absent cookies and unsupported methods are denied. GET and HEAD are modeled as read-only; using them for mutations would undermine this policy regardless of the token checks.
Browsers can attach cookies to some requests initiated from another site. Therefore possession of a valid cookie alone does not show that a state-changing request reflects the user's intent. For POST, PUT, PATCH and DELETE, the fixture requires a nonempty CSRF value matching the one stored in that session. It is not enough to check that any token was submitted. The comparison uses the standard hmac.compare_digest utility; it does not create a signature or implement cryptography.
import hmac
expected = "csrf-for-session-A"
print(hmac.compare_digest("csrf-for-session-B", expected))
print(99 < 100, 100 < 100)Cookie attributes address different browser behaviors. Secure restricts ordinary transmission to secure contexts; HttpOnly prevents JavaScript cookie APIs from reading the value, but scripts can still initiate requests with it. SameSite=Lax reduces some cross-site cookie sending; it is defense in depth, not a replacement for the application's CSRF protection. The __Host- prefix requires Secure, Path=/ and no Domain attribute in supporting browsers. Our helper formats that policy and rejects token characters that could inject additional header syntax.
A CSRF token is not authentication or object authorization, and XSS can defeat many CSRF assumptions by executing within the trusted origin. Deployed applications need the framework's token transport, origin handling and browser tests. CORS controls which cross-origin responses scripts can read; it is not a substitute for preventing unwanted authenticated writes.
In the bug hunts, examine an expiry equality case and a wrong-but-nonempty CSRF token. In the fill and build, preserve the distinction between read-only and state-changing methods. Passing these tests demonstrates a deterministic request policy and cookie string contract, not actual browser enforcement, secure token issuance or resistance to every CSRF technique.