Injection

Go (Gin) Injection Remediation [Apr 2026] [GHSA-r54v-qq87-px5r]

[Updated Apr 2026] Updated GHSA-r54v-qq87-px5r

Overview

Injection vulnerabilities in real-world Go (Gin) apps can lead to severe data exposure, unauthorized data modification, or remote code execution in some scenarios. SQL injection, in particular, arises when user input is concatenated into queries, allowing attackers to alter query logic or access restricted data. OS command injection or template injection may also occur if user input reaches shell invocations or template engines without proper sanitization. The impact can span from data leakage to account compromise, depending on context and the backend services involved. While no CVEs are provided here, these risks are well-known in web frameworks and languages that interact with databases and system processes, making secure coding practices essential for Go (Gin) applications.

Code Fix Example

Go (Gin) API Security Remediation
package main

import (
  "database/sql"
  "fmt"
  "log"
  "net/http"

  "github.com/gin-gonic/gin"
  _ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func main() {
  var err error
  db, err = sql.Open("mysql", "user:password@tcp(localhost:3306)/mydb")
  if err != nil {
    log.Fatal(err)
  }
  defer db.Close()

  r := gin.Default()
  r.GET("/user/vuln", userVulnHandler)
  r.GET("/user/safe", userSafeHandler)
  r.Run(":8080")
}

// Vulnerable example (for reference): escapes are not applied and user input is interpolated into SQL
func userVulnHandler(c *gin.Context) {
  email := c.Query("email")
  query := fmt.Sprintf("SELECT id, name FROM users WHERE email = '%s'", email)
  rows, err := db.Query(query)
  if err != nil {
    c.String(http.StatusInternalServerError, "error")
    return
  }
  defer rows.Close()
  count := 0
  for rows.Next() {
    count++
  }
  c.String(http.StatusOK, fmt.Sprintf("vulnerable: %d rows", count))
}

// Fixed: parameterized query using a placeholder to prevent injection
func userSafeHandler(c *gin.Context) {
  email := c.Query("email")
  rows, err := db.Query("SELECT id, name FROM users WHERE email = ?", email)
  if err != nil {
    c.String(http.StatusInternalServerError, "error")
    return
  }
  defer rows.Close()
  count := 0
  for rows.Next() {
    count++
  }
  c.String(http.StatusOK, fmt.Sprintf("safe: %d rows", count))
}

CVE References

Choose which optional cookies to allow. You can change this any time.