Homework — stage the attack, check prod
Make it yours.
-
Stage the attack. Save this as a file on your disk and open it in the browser while logged in:
<form action="http://localhost:8080/logout" method="post"><button>Click me</button></form>Click the button. It's a POST to
/logoutfrom a different origin (afile://page), carrying your session cookie — exactly the CSRF shape. It's rejected (no token), and you stay logged in. Now compare: the real Log out button in SignFlow's own header works, because its form carries the token. That's the whole defense, seen from both sides. -
Prove prod stays strict. Run with
APP_ENV=prod SESSION_SECRET=test go run ./cmd/signflow. The plaintext exemption is now skipped. A POST with noOrigin/Refereris rejected — the strict origin check is armed even though you're still on http locally. (This is what protects the deployed site; the dev bypass is genuinely dev-only.) -
Read the token cookie. In DevTools → Cookies, find
_gorilla_csrf. That's the cookie half; the hidden field is the form half. The middleware checks they correspond. Delete the cookie, reload the form, submit → 403 again, now for the token reason rather than the referer reason. Two independent checks, each able to fail on its own.
Where this is going. Auth is nearly complete — register, login, logout, all CSRF-protected. One flow remains: what if a user forgets their password? Lesson 7 builds password reset, and with it the email.Sender interface — a console sender that prints the reset link straight to your terminal so you can complete the whole flow with no API key, and a Resend-backed sender for production. The reset token is single-use and hashed at rest (the sessions pattern again), and completing a reset burns every session and outstanding token — a password change should log out every device.