Injection

Injection in Go (Gin) Remediation Guide [GHSA-x783-xp3g-mqhp]

[Updated Apr 2026] Updated GHSA-x783-xp3g-mqhp

Overview

Injection vulnerabilities in Go (Gin) can have severe real-world impact. If an API builds SQL queries or executes shell commands by directly concatenating user-supplied input, attackers can alter the query logic, bypass authentication, read or modify data, or run arbitrary commands on the host with the privileges of the application. In web services implemented with Gin, this risk commonly arises in handlers that interpolate request parameters into raw SQL or system-level commands without proper validation or parameterization. The consequences include data leakage, data corruption, privilege escalation, and even remote code execution if OS commands are involved. Attackers may exploit poorly sanitized inputs via query strings, form data, or JSON payloads, potentially impacting any downstream services connected to the database or system. Even if the surface appears limited to a single endpoint, the blast radius can be substantial if the compromised endpoint guards access to sensitive operations or if the same database user exists across multiple services. Proactive mitigation focuses on eliminating dynamic SQL construction and enforcing strict input handling, especially in high-risk routes.

Code Fix Example

Go (Gin) API Security Remediation
package main

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

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

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

  r := gin.Default()

  // Vulnerable endpoint: builds SQL with string concatenation from user input
  r.GET("/vuln/user", func(c *gin.Context){
    id := c.Query("id") // user-supplied input
    query := "SELECT name FROM users WHERE id = " + id
    var name string
    if err := db.QueryRow(query).Scan(&name); err != nil {
      c.String(http.StatusInternalServerError, "error")
      return
    }
    c.String(http.StatusOK, "User: %s", name)
  })

  // Fixed endpoint: uses parameterized query to prevent injection
  r.GET("/secure/user", func(c *gin.Context){
    id := c.Query("id")
    var name string
    if err := db.QueryRow("SELECT name FROM users WHERE id = ?", id).Scan(&name); err != nil {
      c.String(http.StatusInternalServerError, "error")
      return
    }
    c.String(http.StatusOK, "User: %s", name)
  })

  r.Run(":8080")
}

CVE References

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