We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

CSRF Tokens

A CSRF token proves that a state-changing request includes a secret issued by the application, not just a cookie the browser attached automatically.

The synchronizer token pattern stores a random token in the user's server-side session. Generate it with crypto/rand when the session is created:

tokenBytes := make([]byte, 32)
if _, err := rand.Read(tokenBytes); err != nil {
    return err
}
csrfToken := base64.RawURLEncoding.EncodeToString(tokenBytes)

Render that token in each protected form:

<input type="hidden" name="csrfToken" value="{{.CSRFToken}}" />

When the form is submitted, compare its token with the authenticated session's token. subtle.ConstantTimeCompare avoids a comparison whose timing varies with the matching prefix. Check the lengths first because different-length values can never match.

An attacker's page can trigger a request carrying the victim's cookie, but the same-origin policy prevents it from reading a form to obtain the token.

XSS can bypass CSRF tokens by reading one from the DOM and submitting a valid request. You need to prevent both vulnerabilities.

Assignment

Bearly Secure's forms already carry per-session CSRF tokens, and most mutation handlers already verify them. There are two problems: sessions.CSRFTokensMatch is a stub that accepts every token, and the checkout handler never verifies its submitted token.

Implement the token comparison, then protect checkout.

With Bearly Secure still running, run and submit the CLI tests from the project root.