Amblem
Furkan Baytekin

What is a CSRF Token and How to Implement It in Go

Protect your apps from CSRF attacks with this complete implementation guide

What is a CSRF Token and How to Implement It in Go
150
4 minutes

Introduction

If you’ve ever dealt with user authentication and forms on the web, you’ve probably heard of CSRF or Cross-Site Request Forgery. It’s a common security vulnerability that, if left unchecked, can allow attackers to trick users into performing unwanted actions.

In this post, we’ll demystify CSRF, understand how CSRF tokens work, and walk through a clean implementation using Go. Whether you’re building a small web app or a production-grade backend, this guide will help you secure your endpoints from this sneaky threat.


What is CSRF (Cross-Site Request Forgery)?

CSRF is a type of attack that tricks an authenticated user into performing an action they didn’t intend to. It exploits the trust a site has in the user’s browser.

Example Scenario:

  1. You’re logged into your bank account.
  2. You visit a malicious site in another tab.
  3. That site secretly sends a request like POST /transfer to your bank.
  4. Since you’re already authenticated (your session cookie is automatically sent), the request goes through.

Boom 💥 — money transferred without your consent.


How Do CSRF Tokens Work?

A CSRF token is a random, secret value that your server generates and attaches to every form or state-changing request. The server then validates this token with each request.

The Flow:

  1. Server generates a CSRF token per session.
  2. Token is embedded in every form or AJAX request.
  3. When the user submits the form, the token is sent back.
  4. Server checks if the token matches the one in the session.
  5. If valid ➝ process request. If not ➝ block it.

How to Implement CSRF Protection in Go

We’ll use Go’s standard net/http and a handy middleware package called gorilla/csrf to keep things simple and secure.

📦 Step 1: Install the gorilla/csrf package

bash
go get github.com/gorilla/csrf

🛠️ Step 2: Basic Setup with Middleware

go
package main import ( "fmt" "net/http" "github.com/gorilla/csrf" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() csrfMiddleware := csrf.Protect( []byte("32-byte-long-auth-key-123456789012"), csrf.Secure(false), // Set to true in production (requires HTTPS) ) r.HandleFunc("/form", showFormHandler) r.HandleFunc("/submit", submitHandler).Methods("POST") http.ListenAndServe(":8080", csrfMiddleware(r)) }

📝 Step 3: Displaying the CSRF Token in a Form

go
func showFormHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") form := fmt.Sprintf(` <form action="/submit" method="POST"> <input type="hidden" name="%s" value="%s"> <input type="text" name="message"> <input type="submit" value="Submit"> </form> `, csrf.TokenFieldName, csrf.Token(r)) w.Write([]byte(form)) }

csrf.Token(r) grabs the token for the current request. csrf.TokenFieldName gives you the token’s field name (gorilla.csrf.Token by default).


📩 Step 4: Handling the POST Request

go
func submitHandler(w http.ResponseWriter, r *http.Request) { message := r.FormValue("message") fmt.Fprintf(w, "Received: %s", message) }

The CSRF middleware automatically checks the token. If it’s missing or invalid, it returns a 403 Forbidden and stops execution.


Tips for Production


When Not to Use CSRF Protection

If your app is fully stateless (e.g. uses JWT tokens and no cookies), CSRF isn’t a concern. But for any session-based login (with cookies), CSRF protection is critical.


Conclusion

CSRF tokens are a must-have security measure for any web app dealing with authenticated users. With Go, and the help of the Gorilla CSRF middleware, implementing protection is straightforward and effective.

✅ Generate a token ✅ Add it to forms ✅ Let middleware do the validation

That’s it! Now your users are safe from sneaky cross-site requests.


Album of the day:

Suggested Blog Posts