FlawOpen

flawopen.com/SQL-инъекции в Go/GORM Raw SQL и SQL-инъекции

Защищает ли GORM Raw() от SQL-инъекций? Параметры в Go

CWE-89: SQL InjectionСправочная страница
Краткий ответ

Представьте placeholder как запечатанный конверт для значения: драйвер отправляет значение отдельно от инструкций SQL. GORM Raw() может безопасно привязать его, если placeholder остается в запросе, а значение передается аргументом. Форматирование пользовательского ввода в строку SQL смешивает конверт с инструкциями и может изменить запрос.

НЕБЕЗОПАСНО
// Пользовательский текст становится синтаксисом SQL
db.Raw(fmt.Sprintf(
  "SELECT * FROM users WHERE id = %s",
  userID,
)).Scan(&user)
БЕЗОПАСНО
// Драйвер привязывает userID как значение
db.Raw(
  "SELECT * FROM users WHERE id = ?",
  userID,
).Scan(&user)

Безопасный GORM Raw SQL и привязка параметров

GORM и Go database/sql привязывают значения, если placeholders остаются в SQL, а аргументы передаются отдельно, например db.Where("name = ?", userInput) или db.Raw("SELECT ... WHERE id = ?", userID). Placeholder обозначает значение, а не синтаксис SQL: имена таблиц и столбцов, порядок сортировки и операторы нельзя защитить привязкой значения. Выбирайте динамические идентификаторы из фиксированного списка разрешений. Методы Order, Select, Table и Raw уязвимы, если пользовательский ввод конкатенируется с фрагментами SQL.

Поиск в кодовой базе

rg -n --glob '*.go' '\.(Raw|Exec|Order|Select|Table)\s*\(' . rg -n --glob '*.go' 'fmt\.(Sprintf|Sprint)' .

Частые вопросы о GORM Raw SQL и параметрах

Всегда ли безопасны цепочечные методы GORM?

Нет. Условия с отдельно передаваемыми значениями, например Where("name = ?", input), используют привязку параметров. Конкатенация ввода в строку условия или передача сырого синтаксиса SQL все еще могут внедрить запрос. Некоторые методы принимают неэкранированные идентификаторы или SQL-фрагменты; проверяйте аргументы и разрешайте динамическую структуру только по спискам.

Можно ли привязать placeholder к имени таблицы или столбца?

Нет. Placeholders представляют значения данных. Для динамического идентификатора или сортировки выбирайте фиксированные варианты, определенные приложением, и вставляйте в SQL только проверенную константу.

Официальные источники и справка

См. также SQL-инъекции (CWE-89): как они работают и как их предотвратить в любом языке — flawopen.com Достаточно ли экранировать кавычки от SQL Injection? Достаточно ли ORM, чтобы предотвратить SQL-инъекции? Защищает ли Knex.js от SQL-инъекций? MyBatis ${} и #{}: защита от SQL Injection MySQLi и PDO: безопасные подготовленные запросы Защищает ли NHibernate от SQL-инъекций?