Access and accounts
Check on the server who is asking and what they may do, on every request. Make accounts hard to guess, steal or take over.
- Required 12
- Recommended 1
Required
Check ownership on every record
RequiredBefore returning or changing a record, check on the server that it belongs to the logged-in user or their team.
Check roles on every action
RequiredCheck the user's role on the server for every admin or staff action. Hiding a button is not a check.
Deny by default
RequiredMake every route need a login unless it is marked public on purpose.
Slow down password guessing
RequiredLimit failed logins per account and per address, offer two-factor login, and refuse passwords known from breaches.
Store passwords with a slow hash
RequiredStore passwords only as a slow, salted hash made for passwords, such as Argon2id or bcrypt.
Lock down session cookies
RequiredMark session cookies
HttpOnly,SecureandSameSite=LaxorStrict. Issue a new session at login and end it at logout and after a time limit.Block cross-site form posts
RequiredMake sure a change of state only comes from your own pages, with
SameSitecookies plus a token or an origin check.Make password resets safe
RequiredSend a long random reset link that works once, expires within an hour, and says the same thing whether the account exists or not.
Accept only the fields you expect
RequiredCopy only named fields from a request into a record. Never save the whole request body.
Verify every token
RequiredCheck the signature, algorithm, expiry and audience of every signed token, such as a JWT. Keep tokens short-lived.
Offer two-factor login
RequiredOffer a second factor to every user, and require it for staff and admin accounts. Prefer passkeys, which phishing cannot steal.
Deny access when a check fails
RequiredWhen a permission check, token check or policy lookup throws an error or times out, refuse the request. Never let an error grant access.
Recommended
Compare secrets in constant time
RecommendedCompare tokens, signatures and codes with a constant-time function, so response times reveal nothing about how close a guess was.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers security testing playbook: https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts.