Cross Site Request Forgery in Gin with Cockroachdb
Cross Site Request Forgery in Gin with Cockroachdb — how this specific combination creates or exposes the vulnerability
Cross Site Request Forgery (CSRF) in a Gin application using CockroachDB arises from the interaction between HTTP request handling, session management, and database operations. Gin does not provide built-in CSRF protection, so if developers rely solely on cookie-based sessions without anti-CSRF tokens, authenticated requests can be forged from malicious origins. CockroachDB, as a distributed SQL database, does not inherently prevent CSRF; it stores and serves data as instructed by the application. The vulnerability manifests when a Gin handler performs state-changing operations (POST, PUT, DELETE) based on cookies for authentication without verifying request origin or including a per-request token.
Consider a user authenticated via a session cookie stored in the browser. If a malicious site crafts a request to the Gin endpoint that updates a user’s email in CockroachDB, and the user has an active session, the request may be executed with the user’s privileges. CockroachDB will apply the SQL statement because the application passes authenticated credentials (e.g., a user ID from a cookie or JWT) without validating the request source. Common patterns that expose the attack surface include:
- Endpoints that accept JSON or form values identifying a user ID without ensuring the requesting user matches that ID.
- Lack of SameSite cookie attributes and missing anti-CSRF tokens for state-changing methods.
- Use of GET requests for operations that change data in CockroachDB, which can be triggered by image tags or iframes from malicious sites.
Because middleBrick scans unauthenticated attack surfaces and tests inputs across security checks including BOLA/IDOR and Input Validation, it can surface endpoints where CSRF-like behaviors intersect with insecure data access patterns. The scanner does not exploit these conditions but highlights findings with severity and remediation guidance, helping developers correlate risks across authentication, authorization, and database interaction layers.
Cockroachdb-Specific Remediation in Gin — concrete code fixes
Remediation centers on ensuring every state-changing request is intentional and tied to the authenticated user. Implement anti-CSRF tokens for forms and AJAX requests, enforce SameSite and Secure cookie attributes, and validate ownership on every database operation. Below are concrete examples using CockroachDB with Gin.
1. Anti-CSRF token with form submission
Generate a per-session or per-request token, store it in the session, and require it for state-changing endpoints. This ensures requests originate from your application.
// Example using gorilla/session and a random token generator
package main
import (
"github.com/gin-gonic/gin"
"github.com/gorilla/session"
"net/http"
"crypto/rand"
"encoding/base64"
)
var store = session.NewCookieStore([]byte("your-32-byte-long-key-here-key-here"))
func generateToken() (string, error) {
b := make([]byte, 32)
_, err := rand.Read(b)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b), nil
}
func setCSRFToken(c *gin.Context) {
session, _ := store.Get(c.Request, "session-name")
token, err := generateToken()
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "server error"})
return
}
session.Values["csrf_token"] = token
session.Save(c.Request, c.Writer)
c.Set("csrf_token", token)
}
func validateCSRFToken(c *gin.Context) {
session, _ := store.Get(c.Request, "session-name")
token, ok := session.Values["csrf_token"].(string)
if !ok || c.PostForm("csrf_token") != token {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "invalid csrf token"})
return
}
c.Next()
}
func updateEmailHandler(c *gin.Context) {
// token validated via middleware
userID := c.Param("userID")
newEmail := c.PostForm("email")
// Execute CockroachDB query with userID and newEmail after ensuring userID matches authenticated user
// db.ExecContext(...)
c.JSON(http.StatusOK, gin.H{"status": "email updated"})
}
func main() {
r := gin.Default()
r.Use(func(c *gin.Context) {
setCSRFToken(c)
c.Next()
})
r.POST("/users/:userID/email", validateCSRFToken(), updateEmailHandler)
r.Run()
}
2. Secure cookies and SameSite attributes
Ensure session cookies are not sent in cross-site requests by setting SameSite=Strict or Lax, and Secure if served over HTTPS.
func main() {
r := gin.Default()
store := session.NewCookieStore([]byte("your-32-byte-long-key-here-key-here"))
store.Options = &sessions.Options{
Path: "/",
MaxAge: 3600,
HttpOnly: true,
Secure: true, // set true in production with HTTPS
SameSite: http.SameSiteStrictMode,
}
// assign store to context or use a wrapper
r.Use(func(c *gin.Context) {
session, _ := store.Get(c.Request, "session-name")
c.Set("session", session)
c.Next()
})
// routes
r.Run()
}
3. Validate ownership before CockroachDB writes
Even with tokens and secure cookies, always verify that the authenticated user is allowed to act on the target resource. Use the authenticated user ID from session or JWT, and include it in the WHERE clause of your CockroachDB SQL.
import "github.com/jackc/pgx/v5/pgxpool"
func updateUserEmail(pool *pgxpool.Pool, userIDFromSession int64) gin.HandlerFunc {
return func(c *gin.Context) {
requestedID := c.Param("userID")
// Ensure the requested user matches the authenticated user
if requestedID != userIDFromSession {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "forbidden"})
return
}
var newEmail string
if err := c.BindJSON(&newEmail); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid payload"})
return
}
// Safe: userIDFromSession is used as the owner guard
_, err := pool.Exec(c, `
UPDATE users SET email = $1 WHERE id = $2 AND id = $3
`, newEmail, requestedID, userIDFromSession)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "db error"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "updated"})
}
}
These patterns address CSRF by combining origin verification (tokens and cookie attributes) with strict ownership checks in CockroachDB queries. middleBrick’s scans can highlight endpoints that lack such protections by correlating authentication, BOLA/IDOR, and input validation checks, providing findings and remediation guidance rather than automatic fixes.