Injection

Injection in Go (Gin): SQLi Remediation [CVE-2026-33350]

[Updated April 2026] Updated CVE-2026-33350

Overview

The CVE-2026-33350 vulnerability in LORIS describes an SQL injection in the MRI feedback popup window of the imaging browser, allowing attackers to manipulate or exfiltrate data by injecting malicious SQL into input fields. This is categorized under CWE-89 and was fixed in LORIS versions 27.0.3 and 28.0.1. Although LORIS is not written in Go, this guide uses a Go (Gin) demonstration to illustrate how similar SQL injection risks arise in Go web applications when user input is concatenated into SQL strings. In the real world, such injections could yield unauthorized data access, data modification, or even broader server compromise if the attacker can escalate privileges or access administrative data stores. Remediation should treat SQL injection as a top risk in any API that consumes user input for database queries.

Affected Versions

LORIS MRI feedback related vulnerability prior to 27.0.3 and 28.0.1; CVE-2026-33350

Code Fix Example

Go (Gin) API Security Remediation
package main

import (
  "database/sql"
  _ "github.com/mattn/go-sqlite3"
  "github.com/gin-gonic/gin"
  "log"
  "net/http"
)

func main() {
  db, err := sql.Open("sqlite3", ":memory:")
  if err != nil { log.Fatal(err) }
  defer db.Close()

  // initialize schema and data
  _, err = db.Exec("CREATE TABLE users(id INTEGER PRIMARY KEY, username TEXT, role TEXT)")
  if err != nil { log.Fatal(err) }
  _, _ = db.Exec("INSERT INTO users(username, role) VALUES('alice','admin'),('bob','user')")

  r := gin.Default()

  // Vulnerable handler (demonstrates the pattern to avoid)
  r.GET("/vuln", func(c *gin.Context) {
    username := c.Query("username")
    // Vulnerable: direct string concatenation with user input
    row := db.QueryRow("SELECT id, username, role FROM users WHERE username = '" + username + "'")
    var id int
    var uname string
    var role string
    if err := row.Scan(&id, &uname, &role); err != nil {
      c.String(http.StatusOK, "No result: %v", err)
      return
    }
    c.JSON(http.StatusOK, gin.H{"id": id, "username": uname, "role": role})
  })

  // Fixed handler (secure pattern)
  r.GET("/fixed", func(c *gin.Context) {
    username := c.Query("username")
    row := db.QueryRow("SELECT id, username, role FROM users WHERE username = ?", username)
    var id int
    var uname string
    var role string
    if err := row.Scan(&id, &uname, &role); err != nil {
      c.String(http.StatusOK, "No result: %v", err)
      return
    }
    c.JSON(http.StatusOK, gin.H{"id": id, "username": uname, "role": role})
  })

  r.Run(":8080")
}

CVE References

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