package lib import ( "crypto/rand" "encoding/base64" "net/http" "sync" ) var ( csrf_tokens = make(map[string]string) csrf_mutex sync.RWMutex ) func Generate_CSRF_Token() string { b := make([]byte, 32) rand.Read(b) return base64.URLEncoding.EncodeToString(b) } func Get_CSRF_Token(session_id string) string { csrf_mutex.RLock() token, exists := csrf_tokens[session_id] csrf_mutex.RUnlock() if !exists { token = Generate_CSRF_Token() csrf_mutex.Lock() csrf_tokens[session_id] = token csrf_mutex.Unlock() } return token } func Verify_CSRF_Token(session_id, token string) bool { csrf_mutex.RLock() expected := csrf_tokens[session_id] csrf_mutex.RUnlock() return token == expected && token != "" } func Require_CSRF(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { session_id := Get_Session_ID(r) if err := r.ParseForm(); err != nil { http.Error(w, "Invalid form data", http.StatusBadRequest) return } token := r.FormValue("csrf_token") if !Verify_CSRF_Token(session_id, token) { http.Error(w, "Invalid CSRF token", http.StatusForbidden) return } } next(w, r) } }