Chapter 5 of 8 · 3 checks · 2 min
CSRF and cookies
Cookies carry your sessions, so their flags matter. These checks stop other sites from using your users' cookies against them.
Set HttpOnly, Secure and SameSite on session cookiesMust
Why it matters and how to check
HttpOnlykeeps session cookies away from JavaScript, so an XSS bug cannot read them.Securekeeps them off plain HTTP.SameSite=LaxorStrictstops most cross-site requests from carrying them. The__Host-prefix adds a guard that the cookie was set by your exact host over HTTPS with noDomainattribute.To verify, open dev tools, go to Application then Cookies, and check each auth cookie. All three flags should be set. Then run
document.cookiein the console and confirm the session cookie is not listed.Example
HTTP Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=LaxProtect state-changing requests with a CSRF token or Fetch Metadata checkMust
Why it matters and how to check
OWASP treats SameSite as defense in depth, not the main CSRF defense. Use your framework's built-in protection first. Otherwise use a synchronizer token for stateful apps, a signed double-submit cookie for stateless ones, or reject unsafe methods when
Sec-Fetch-Siteiscross-site, falling back to anOrigincheck for older browsers.To verify, build a tiny HTML page on another origin that auto-submits a form to one of your POST endpoints while you are signed in. The request must be rejected. Repeat for a JSON endpoint using
fetchwithcredentials: 'include'.Never change state with a GET requestMust
Why it matters and how to check
SameSite=Laxstill sends cookies on top-level GET navigation, and GET URLs end up in logs, previews and prefetches. A link like/account/delete?confirm=1can be triggered by an image tag or a link preview bot.To verify, list every route that writes to the database, sends email or spends credits, and confirm none of them accepts GET. Check email links like unsubscribe or approve too: they should open a page that then submits a POST, or use a signed, single-purpose token.