В Postgres подготовленные запросы и пользовательские функции эквивалентны как механизм защиты от внедрения SQL ?
Есть ли конкретные преимущества в одном подходе по сравнению с другим?
В Postgres подготовленные запросы и пользовательские функции эквивалентны как механизм защиты от внедрения SQL ?
Есть ли конкретные преимущества в одном подходе по сравнению с другим?
Ответы:
Это зависит.
С LANGUAGE sql
ответом, как правило, да .
Переданные параметры обрабатываются как значения, и внедрение SQL невозможно, если вы не вызываете небезопасные функции из тела и не передаете параметры.
С LANGUAGE plpgsql
ответом, как правило, да .
Однако PL / pgSQL допускает динамический SQL, где переданные параметры (или части) объединяются в строку запроса и выполняются с помощью EXECUTE
. Это может преобразовать пользовательский ввод в код SQL и сделать возможным внедрение SQL . Вы не можете сказать извне, правильно ли обрабатывает тело функции. Инструменты предоставляются.
Используйте динамический SQL только там, где вам это нужно. Простые операторы SQL, использующие параметры в качестве значений, защищены от внедрения SQL, как функции SQL.
Для динамического SQL желательно передавать значения как значения с помощью:
USING
положение. Пример .Делает SQL-инъекцию невозможной на главной.
Если вы объединяете значения в строке SQL, используйте:
Безопасно заключает строки в одинарные кавычки , что позволяет избежать синтаксических ошибок и внедрения SQL.
Параметры процесса, которые должны обрабатываться как идентификаторы в строке SQL с помощью:
format()
с указателем формата%I
. Пример .quote_ident()
, Пример .regclass
для имен таблиц: _tbl::regclass
. Пример .Заключает строки в двойных кавычках безопасны в случае необходимости , что позволяет избежать синтаксических ошибок и SQL инъекции.
Связанный:
Никогда не создавайте строку из пользовательского ввода и выполняйте. Это включает в себя идентификаторы, непосредственно переданные пользователем или полученные из системного каталога. При построении динамического SQL все должно обрабатываться как вводимые пользователем данные и безопасно цитироваться!
Подробнее о влиянии на производительность в этом связанном ответе:
Основы SQL-инъекции:
Аналогичные соображения применимы и к другим языкам на стороне сервера, которые допускают динамический SQL.
USING
условие для передачи значений, EXECUTE
когда это возможно. Вы можете вызвать функцию PL / pgSQL из функции SQL и передать параметры. Итак, чтобы быть абсолютно правильным, вы в безопасности, если вы не вызываете небезопасные функции прямо или косвенно. Если все ваши функции выполнены правильно, это не может произойти.