четверг, 9 сентября 2021 г.

Как избежать риска внедрения SQL-кода с пакетом database/sql в Golang

Вы можете избежать риска внедрения SQL-кода, указав значения параметров SQL в качестве аргументов функции пакета sql. Многие функции в пакете sql предоставляют параметры для оператора SQL и значений, которые будут использоваться в параметрах этого оператора (другие предоставляют параметр для подготовленного оператора и параметров).

Код в следующем примере использует символ ? символ в качестве заполнителя для параметра id, который предоставляется как аргумент функции:

// Правильный формат для выполнения оператора SQL с параметрами.
rows, err := db.Query("SELECT * FROM user WHERE id = ?", id)

Функции пакета sql, выполняющие операции с базой данных, создают подготовленные операторы из предоставленных вами аргументов. Во время выполнения пакет sql превращает инструкцию SQL в подготовленную инструкцию и отправляет ее вместе с отдельным параметром.

Примечание. Заполнители параметров различаются в зависимости от СУБД и используемого драйвера. Например, драйвер pq для Postgres принимает форму-заполнитель, такую ​​как $1 вместо ?.

У вас может возникнуть соблазн использовать функцию из пакета fmt для сборки оператора SQL в виде строки с включенными параметрами - например:

// SECURITY RISK!
rows, err := db.Query(fmt.Sprintf("SELECT * FROM user WHERE id = %s", id))

Это небезопасно! Когда вы это делаете, Go собирает весь оператор SQL, заменяя глагол формата %s значением параметра перед отправкой полного оператора в СУБД. Это создает риск внедрения SQL-кода, поскольку вызывающий код может отправить неожиданный фрагмент SQL в качестве аргумента id. Этот фрагмент может завершить инструкцию SQL непредсказуемым образом, что опасно для вашего приложения.

Например, передав определенное значение %s, вы можете получить что-то вроде следующего, которое может вернуть все пользовательские записи в вашей базе данных:

SELECT * FROM user WHERE id = 1 OR 1=1;


Читайте также:


Комментариев нет:

Отправить комментарий