Какие существуют способы защиты от SQL-инъекций в Go?

Ответ

Основной и самый надежный способ защиты от SQL-инъекций — это использование подготовленных выражений (prepared statements) с параметризованными запросами. Этот подход разделяет саму SQL-команду и данные, которые в нее подставляются. Драйвер базы данных отправляет их серверу раздельно, что исключает возможность интерпретации пользовательского ввода как части SQL-кода.

Пример с database/sql:

// ? является плейсхолдером для параметра
stmt, err := db.Prepare("SELECT id, name FROM users WHERE email = ?")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

// Передаем пользовательский ввод как параметр, а не вставляем в строку запроса
rows, err := stmt.Query(emailInput)
// ...

Дополнительные, но не менее важные, меры:

  • Использование ORM: Библиотеки, такие как GORM или sqlc, по умолчанию используют подготовленные выражения, что снижает риск ошибки.
  • Валидация и санация входных данных: Всегда проверяйте и очищайте данные, поступающие от пользователя, на соответствие ожидаемому формату (например, что ID — это число, а email — валидный адрес).
  • Принцип наименьших привилегий: Предоставляйте пользователю базы данных только те права, которые ему действительно необходимы. Например, пользователю, который только читает данные, не нужны права на UPDATE или DELETE.
  • Избегайте конкатенации строк: Никогда не создавайте SQL-запросы путем простого сложения строк с пользовательским вводом. Это прямой путь к уязвимости.

Для динамического построения запросов, где количество условий заранее неизвестно, используйте специальные библиотеки-конструкторы запросов (query builders), например, Squirrel или sqlx, которые помогают безопасно формировать сложные запросы.