Cross-Site Request Forgery in Go Lang
Prevention in Go
Go does not provide a built-in protection against CSRF attacks; developers must manually implement protections by checking the anti-CSRF tokens or using one of the many, well-tested libraries and frameworks.
Using the standard http
library, the double submit cookie technique can be implemented as follows. To generate a random string to be used as a token, the crypto/rand
package can be used, for example:
func GenerateNonce() (string, error) {
b := make([]byte, 16)
_, err := rand.Read(b)
return fmt.Sprintf("%x", b), err
}
Assuming the html/template
package is used to render HTML pages, the CSRF token can be added to the form using the following template snippet:
<form action="/action" method="POST">
<input type="hidden" name="csrfToken" value="{{ .CsrfToken }}"/>
</form>
Additionally, the same token must be set as a cookie value in the same response, for example:
http.SetCookie(w, &http.Cookie{
Name: "csrfToken",
Value: csrfToken,
})
Finally, the implementation of /action
determines if the request is legit by checking that the CSRF token is the same in the cookie and the form:
cookieCsrfToken, err := r.Cookie("csrfToken")
requestCsrfToken := r.Form.Get("csrfToken")
if err != nil || cookieCsrfToken.Value != requestCsrfToken {
w.WriteHeader(http.StatusForbidden)
return
}
References
OWASP - Cross-Site Request Forgery Cheat Sheet MITRE - CWE 352