I want to implement a CSRF warning in my Go web application. Users are not logged in, but fill out forms and pay (via Stripe Checkout).
Posting something sets the key in the session variable (cookie) so that later they can edit what they placed, and the URL in the email allows them to return when the cookie has expired, and if necessary, edit it.
From what I see, I can use https://code.google.com/p/xsrftoken/ with the double cookie method to implement CSRF prevention:
Create a CSRF token for an arbitrary user ID (uuid.V4 () via go-uuid ), for example:
if session.Values["id"] == "" {
session.Values["id"] = uuid.NewV4()
}
csrfToken := xsrftoken.Generate(csrfKey, session.Values["id"], "/listing/new/post")
... and save this in the session and display in a hidden field in the template:
session.Values["csrfToken"] = csrfToken
...
<input type="hidden" id="_csrf" value={{ .csrfToken }}>
When the user submits the form, I need to get the identifier that I generated, confirm that the one presented csrfTokenfrom the form matches the one that was in the session, and if so, check it with the xsrf package to confirm that it expired:
userID := session.Values["id"]
if session.Values["csrfToken"] != r.PostFormValue("csrfToken") {
http.Redirect(w, r, "/listing/new", 400)
}
if !xsrftoken.Valid(session.Values["csrfToken"], csrfKey, userID, "/listing/new/post") {
http.Redirect(w, r, "/listing/new", 400)
}
I have the following questions:
Should I generate a new token every time a form is displayed? Or is reuse of a token without expiration acceptable for a single user session? Refresh . According to this answer, I should only generate a new token per session (i.e. the same user receives the same token in the same form until the token expires)
, , , , ? (, 10 , ) ( , !) id + csrf ?
/li >? Coding Horror , SO HTML-, ? xsrf, , ?
?