Link Search Menu Expand Document

Cross-Site Request Forgery in Go Lang

Play SecureFlag Play Go Lang Labs on this vulnerability with SecureFlag!

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