Overview
Injection vulnerabilities in Go (Gin) empower attackers to alter queries, exfiltrate data, bypass authentication, or crash services. In production Go APIs, an attacker can craft input via query parameters, JSON, or form fields to influence SQL logic or command execution when user data is interpolated into runtime strings. The impact includes data breaches, regulatory exposure, and reputational damage. This guide describes general injection risks in this framework; no CVEs are provided here.
Code Fix Example
Go (Gin) API Security Remediation
package main
import (
"database/sql"
"log"
"net/http"
"github.com/gin-gonic/gin"
_ "github.com/mattn/go-sqlite3"
)
func setupDB() *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil { log.Fatal(err) }
if _, err := db.Exec("CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT)"); err != nil {
log.Fatal(err)
}
if _, err := db.Exec("INSERT INTO users (username) VALUES ('alice'), ('bob')"); err != nil {
log.Fatal(err)
}
return db
}
func vulnerableQuery(db *sql.DB, username string) (int, error) {
var count int
row := db.QueryRow("SELECT COUNT(*) FROM users WHERE username = '" + username + "'")
if err := row.Scan(&count); err != nil {
return 0, err
}
return count, nil
}
func safeQuery(db *sql.DB, username string) (int, error) {
var count int
if err := db.QueryRow("SELECT COUNT(*) FROM users WHERE username = ?", username).Scan(&count); err != nil {
return 0, err
}
return count, nil
}
func main() {
r := gin.Default()
db := setupDB()
r.GET("/vuln", func(c *gin.Context) {
user := c.Query("user")
count, err := vulnerableQuery(db, user)
if err != nil {
c.String(http.StatusInternalServerError, "error")
return
}
c.String(http.StatusOK, "count=%d", count)
})
r.GET("/fix", func(c *gin.Context) {
user := c.Query("user")
count, err := safeQuery(db, user)
if err != nil {
c.String(http.StatusInternalServerError, "error")
return
}
c.String(http.StatusOK, "count=%d", count)
})
r.Run(":8080")
}