Skip to main content

Module session

Module session 

Source
Expand description

Session tokens, the cookie they travel in, the extractors that resolve them, the CSRF check, and the login rate limiter.

§The token

32 bytes from the system CSPRNG, base64url-unpadded (43 characters, cookie- safe unquoted). Stored as hex(SHA-256(token)) and never in plaintext, so a read of the database — a backup, a .dump, an injection — yields nothing replayable. Not the password KDF: the token has 256 bits of entropy, so there is no dictionary to slow down and a slow hash would buy nothing but latency on every request. Lookup is by the hash, and the value looked up is the secret, so that path needs no constant-time comparison — unlike the CSRF token, which is compared against a caller-supplied string.

§CSRF, and why SameSite=Strict is not enough

The usual answer is that SameSite covers it. It does not, here, and the reason is specific: SameSite is scoped to the registrable domain, not the origin — different ports of the same host are same-site. A panel on :3001 beside anything else on :8080 of the same box is exactly the configuration it does not protect. So there is a per-session token as well, plus an origin gate that also covers login (which by definition carries no session token yet).

Enforcement is structural: one of AuthenticatedWrite, AdminWrite or SelfServiceWrite is the only way for a mutating handler to reach a session, and constructing any of them runs the origin and CSRF checks. The three differ only in the privilege tier they demand — operator+, admin, and none (own-account routes) — so a handler that forgets the role check cannot compile. Same reasoning as hoisting the media-type/crit/url/nonce checks into AcmeRequest — a new endpoint cannot forget what it cannot express.

Structs§

AdminClientIp
The client address of an admin request, if the socket carried one.
AdminRead
Authenticated plus a privilege tier of AdminRole::Admin – the read-side sibling of AdminWrite, with no CSRF or origin gate, since a GET changes nothing.
AdminWrite
AuthenticatedWrite, but requiring the full AdminRole::Admin tier.
Authenticated
A live session and the operator it belongs to. Read-only handlers take this.
AuthenticatedWrite
Authenticated, the origin gate and the CSRF check, plus a privilege tier of at least AdminRole::Operator.
EnrolWrite
A session allowed to set up a factor.
LoginAttempt
One login attempt’s slot in the LoginLimiter.
LoginLimiter
Fixed-window failed-login counter, keyed by client address.
MintedToken
A freshly minted session token, and the hash to store for it.
PendingMfa
A session with a verified password and nothing more.
PendingMfaSubmit
PendingMfa with the origin gate only, and no CSRF check.
SelfServiceWrite
The origin gate, a live active session and the CSRF check – no privilege check, so any role including viewer passes.

Enums§

MfaStep
What still stands between a pending_mfa cookie and a usable session.

Constants§

COOKIE_NAME
The session cookie’s name.
CSRF_HEADER
The header carrying the per-session CSRF token on unsafe methods.
PENDING_MFA_TTL
How long a half-authenticated session may sit unfinished.

Functions§

check_csrf
Compares the request’s X-CSRF-Token against the session’s, in constant time.
check_origin
Refuses a request whose Origin or Sec-Fetch-Site says it came from somewhere else.
clearing_cookie
The Set-Cookie value that clears one.
cookie_value
Reads the session token out of a Cookie header set.
hash_token
hex(SHA-256(token)) — the admin_sessions primary key.
log_login
Logs a completed login attempt. One place, so the events cannot drift.
mint_csrf_token
Mints a CSRF token. Same entropy as a session token — it is stored in plaintext, but it still has to be unguessable.
mint_token
Mints a session token. RNG failure is unrecoverable, as elsewhere in this crate.
session_cookie
The Set-Cookie value that establishes a session.