Ответ
SQL-инъекция — это атака, при которой злоумышленник внедряет вредоносный SQL-код в запрос к базе данных. Это происходит, когда приложение конструирует SQL-запросы путем простой конкатенации строк с пользовательским вводом.
Основной и самый надежный способ борьбы с SQL-инъекциями в Go — параметризация запросов.
Вместо того чтобы вставлять данные напрямую в строку запроса, вы используете специальные маркеры (плейсхолдеры), а сами данные передаете как отдельные аргументы. Драйвер базы данных сам позаботится о безопасном экранировании.
Способы реализации:
-
Позиционные плейсхолдеры (стандартный
database/sql
) Плейсхолдеры зависят от драйвера БД (?
для MySQL,$1
,$2
... для PostgreSQL).// Для PostgreSQL rows, err := db.Query("SELECT name FROM users WHERE id = $1", userID) // Для MySQL rows, err := db.Query("SELECT name FROM users WHERE id = ?", userID)
-
Именованные параметры (библиотека
sqlx
) Улучшает читаемость кода, особенно при большом количестве параметров.user := User{ID: 1, Name: "Alice"} _, err := db.NamedExec(`INSERT INTO users (id, name) VALUES (:id, :name)`, user)
Что нельзя делать: Никогда не конструируйте запросы вот так:
// УЯЗВИМЫЙ КОД!
query := fmt.Sprintf("SELECT name FROM users WHERE id = %s", userID)
rows, err := db.Query(query)
Важно: Параметризация работает только для значений (в WHERE
, VALUES
, SET
). Она не работает для динамических имен таблиц или столбцов. В таких редких случаях необходимо формировать "белый список" разрешенных имен или использовать функцию QuoteIdentifier
из драйвера, если она доступна.