Как параметризация SQL-запроса работает?

В значительной степени все! Daniel Moth покрывает это здесь и здесь . Та единственная листовая поддержка во время выполнения: LINQ к объектам обеспечивается LINQBridge - который оставляет просто большие API как поддержка Выражения и инструменты как LINQ к SQL. Они являются слишком большими, чтобы быть обоснованно портированными назад к.NET 2.0, таким образом, я использовал бы.NET 3.5 для них.

33
задан Wayne Koorts 12 August 2009 в 19:06
поделиться

4 ответа

Параметризованный запрос фактически не выполняет замену строки. Если вы используете подстановку строк, то механизм SQL фактически видит запрос, который выглядит как

SELECT * FROM mytable WHERE user='wayne'

. Если вы используете параметр ? , тогда механизм SQL видит запрос, который выглядит как

SELECT * FROM mytable WHERE user=<some value>

. Это означает, что раньше он даже видит строку «wayne», он может полностью проанализировать запрос и понять, в общем, что делает запрос. Он вставляет «wayne» в собственное представление запроса, а не в строку SQL, описывающую запрос. Таким образом, SQL-инъекция невозможна, поскольку мы уже прошли этап SQL процесса.

(Вышеупомянутое является обобщением, но более или менее передает идею.)

42
ответ дан 27 November 2019 в 18:28
поделиться

Когда вы отправляете запрос через SQL Server, он сначала проверяет кеш процедур. Если он обнаружит, что какой-то запрос ТОЧНО равен, то он будет использовать тот же план и не перекомпилировать запрос, просто заменит заполнители (переменные), но на стороне сервера (db).

проверьте системную таблицу master.dbo.syscacheobjects , и проведите несколько тестов, чтобы узнать больше по этой теме.

0
ответ дан 27 November 2019 в 18:28
поделиться

Использование параметризованных запросов - хороший способ решить задачу по экранированию и предотвращению инъекций в клиентскую библиотеку БД. Он выполнит экранирование до того, как заменит строку на «?». Это делается в клиентской библиотеке перед сервером БД.

Если у вас работает MySQL, включите журнал SQL и попробуйте несколько параметризованных запросов, и вы увидите, что сервер MySQL получает полностью замененные запросы без "?" в нем, но клиентская библиотека MySQL уже избежала кавычек в вашем «параметре» за вас.

Если вы используете метод B с простой заменой строки, "s не экранируются автоматически.

Синергетически с MySQL вы можете заранее подготовить параметризованный запрос, а затем повторно использовать подготовленный оператор позже. Когда вы подготовите запрос, MySQL анализирует его и возвращает вам подготовленный оператор - некоторое проанализированное представление, которое понимает MySQL. Каждый раз, когда вы используете подготовленный оператор, вы не только защищены от внедрения, но и избегаете затрат на повторный анализ запроса.

И, если вы действительно хотите быть в безопасности, вы можете изменить уровень доступа к БД / ORM так что 1) код веб-сервера может использовать только подготовленные операторы и 2) вы можете подготовить операторы только до запуска вашего веб-сервера. Затем, даже если ваше веб-приложение взломано (скажем, с помощью эксплойта переполнения буфера), хакер может использовать только подготовленные операторы, но не более того. Для этого вам нужно заблокировать свое веб-приложение и разрешить доступ к базе данных только через уровень доступа к БД / ORM.

не только вы защищены от внедрения, но и избегаете затрат на повторный анализ запроса.

И, если вы действительно хотите быть в безопасности, вы можете изменить уровень доступа к БД / ORM, чтобы 1) код веб-сервера мог используйте только подготовленные операторы и 2) вы можете подготовить операторы только до запуска вашего веб-сервера. Затем, даже если ваше веб-приложение взломано (например, с помощью эксплойта переполнения буфера), хакер может использовать только подготовленные операторы, но не более того. Для этого вам нужно заблокировать свое веб-приложение и разрешить доступ к базе данных только через уровень доступа к БД / ORM.

не только вы защищены от внедрения, но и избегаете затрат на повторный анализ запроса.

И, если вы действительно хотите быть в безопасности, вы можете изменить уровень доступа к БД / ORM, чтобы 1) код веб-сервера мог используйте только подготовленные операторы, и 2) вы можете подготовить операторы только до запуска вашего веб-сервера. Затем, даже если ваше веб-приложение взломано (скажем, с помощью эксплойта переполнения буфера), хакер может использовать только подготовленные операторы, но не более того. Для этого вам нужно заблокировать свое веб-приложение и разрешить доступ к базе данных только через уровень доступа к БД / ORM.

и 2) вы можете подготовить операторы только до запуска вашего веб-сервера. Затем, даже если ваше веб-приложение взломано (скажем, с помощью эксплойта переполнения буфера), хакер может использовать только подготовленные операторы, но не более того. Для этого вам нужно заблокировать свое веб-приложение и разрешить доступ к базе данных только через уровень доступа к БД / ORM.

и 2) вы можете подготовить операторы только до запуска вашего веб-сервера. Затем, даже если ваше веб-приложение взломано (скажем, с помощью эксплойта переполнения буфера), хакер может использовать только подготовленные операторы, но не более того. Для этого вам нужно заблокировать свое веб-приложение и разрешить доступ к базе данных только через уровень доступа к БД / ORM.

3
ответ дан 27 November 2019 в 18:28
поделиться

Когда вы выполняете замену текста (например, ваш метод B), вы должны опасаться кавычек и тому подобного, потому что сервер получит единственный фрагмент текста, и он должен определить, где значение заканчивается.

С параметризованными операторами, OTOH, сервер БД получает оператор как есть, без параметра. Значение отправляется на сервер в виде отдельного фрагмента данных с использованием простого двоичного безопасного протокола. Следовательно, ваша программа не должна заключать значение в кавычки, и, конечно, не имеет значения, были ли кавычки уже в самом значении.

Аналогия касается исходного и скомпилированного кода: в вашем методе B, вы создаете исходный код процедуры, поэтому вы должны строго соблюдать синтаксис языка. Используя метод A, вы сначала создаете и компилируете процедуру, а затем (сразу после в вашем примере), вы вызываете эту процедуру со своим значением в качестве параметра. И, конечно же, значения в памяти не подлежат синтаксическим ограничениям.

Ммм ... это не совсем аналогия, это действительно то, что происходит под капотом (примерно).

4
ответ дан 27 November 2019 в 18:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: