Skip to content

go.sql_injection

Correctness Critical Common in Incidents

Detects SQL queries built with string concatenation instead of parameterized queries.

SQL injection is a critical security vulnerability:

  • Data theft — Attackers can read your entire database
  • Data destruction — DROP TABLE, DELETE, UPDATE at will
  • Authentication bypass — Log in as any user
  • Privilege escalation — Gain admin access

One unparameterized query can compromise your entire system.

// ❌ Before
query := "SELECT * FROM users WHERE id = " + userID
db.Query(query)
// Also bad
query := fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", name)

If userID is "1 OR 1=1", all users are returned. If name is "'; DROP TABLE users; --", your data is gone.

// ✅ After
db.Query("SELECT * FROM users WHERE id = ?", userID)
// Or with named parameters (sqlx)
db.NamedQuery("SELECT * FROM users WHERE name = :name", map[string]interface{}{"name": name})
  • String concatenation (+) in SQL query strings
  • fmt.Sprintf with SQL keywords
  • strings.Replace on query templates
  • Variable interpolation in queries

Unfault can convert concatenated queries to parameterized form when the query structure is unambiguous.

// PostgreSQL (lib/pq, pgx)
db.Query("SELECT * FROM users WHERE id = $1", id)
// MySQL
db.Query("SELECT * FROM users WHERE id = ?", id)
// SQLite
db.Query("SELECT * FROM users WHERE id = ?", id)
// Multiple parameters - PostgreSQL
db.Query("SELECT * FROM users WHERE id = $1 AND status = $2", id, status)
// Multiple parameters - MySQL
db.Query("SELECT * FROM users WHERE id = ? AND status = ?", id, status)