String Concatenation with pgx Queries
Direct concatenation of user input into SQL queries when using pgx PostgreSQL driver.
Preview example – GO
// Vulnerable
query := "SELECT * FROM users WHERE id = " + userID
row := pool.QueryRow(ctx, query) SQL injection vulnerability in Go applications using the pgx PostgreSQL driver where user input is directly concatenated into SQL queries without proper parameterization.
// VULNERABLE: pgx SQL injection via string concatenation
package main
import (
"context"
"fmt"
"github.com/jackc/pgx/v4/pgxpool"
)
type User struct {
ID int
Name string
Email string
}
func getUserByID(pool *pgxpool.Pool, userID string) (*User, error) {
// VULNERABLE: String concatenation
query := "SELECT id, name, email FROM users WHERE id = " + userID
var user User
err := pool.QueryRow(context.Background(), query).Scan(&user.ID, &user.Name, &user.Email)
return &user, err
}
func searchUsers(pool *pgxpool.Pool, name string) ([]User, error) {
// VULNERABLE: fmt.Sprintf
query := fmt.Sprintf("SELECT id, name, email FROM users WHERE name ILIKE '%%%s%%'", name)
rows, err := pool.Query(context.Background(), query)
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
rows.Scan(&user.ID, &user.Name, &user.Email)
users = append(users, user)
}
return users, nil
}
// Malicious inputs:
// userID: "1 OR 1=1 --"
// name: "'; DROP TABLE users; --"// SECURE: pgx with parameterized queries
package main
import (
"context"
"fmt"
"strconv"
"github.com/jackc/pgx/v4/pgxpool"
)
type User struct {
ID int
Name string
Email string
}
func getUserByID(pool *pgxpool.Pool, userIDStr string) (*User, error) {
// Basic validation
userID, err := strconv.Atoi(userIDStr)
if err != nil || userID <= 0 {
return nil, fmt.Errorf("invalid user ID")
}
// SECURE: $1 placeholder
query := "SELECT id, name, email FROM users WHERE id = $1"
var user User
err = pool.QueryRow(context.Background(), query, userID).Scan(&user.ID, &user.Name, &user.Email)
return &user, err
}
func searchUsers(pool *pgxpool.Pool, name string) ([]User, error) {
// SECURE: $1 placeholder
query := "SELECT id, name, email FROM users WHERE name ILIKE $1"
rows, err := pool.Query(context.Background(), query, "%"+name+"%")
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
rows.Scan(&user.ID, &user.Name, &user.Email)
users = append(users, user)
}
return users, nil
}The vulnerable code uses string concatenation and fmt.Sprintf to build pgx SQL queries, allowing injection attacks. The fixed version uses parameterized queries with $1, $2, etc. placeholders, implements comprehensive input validation, uses transactions for consistency, and demonstrates prepared statements for performance.
Direct concatenation of user input into SQL queries when using pgx PostgreSQL driver.
Sourcery automatically identifies go pgx postgresql sql injection and many other security issues in your codebase.