ПрограммированиеFullstack разработчик

Расскажите о параметризованных запросах и динамическом SQL. Когда использовать каждый подход, какие риски связаны с динамическим SQL и как их избежать? Приведите примеры.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Параметризованные запросы позволяют передавать значения в запрос через специальные параметры, а не напрямую через подстановку переменных. Это повышает безопасность и защищает от SQL-инъекций, а также ускоряет выполнение повторяющихся запросов за счёт кэширования плана.

Динамический SQL позволяет строить и выполнять запросы на лету (например, через EXEC sp_executesql в MS SQL или PREPARE/EXECUTE в PostgreSQL). Необходимо быть очень осторожным: подстановка значений непосредственно в текст запроса может привести к SQL-инъекциям, ошибкам синтаксиса и плохой производительности.

Пример параметризованного запроса (на Python с библиотекой psycopg2):

cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

Пример динамического SQL в PostgreSQL:

EXECUTE format('SELECT * FROM %I WHERE value = %L', tablename, value);

Вопрос с подвохом.

Вопрос: Почему просто экранировать кавычки ('), как это делают некоторые старые приложения, недостаточно для защиты от SQL-инъекций?

Ответ:

Экранирование кавычек не защитит от всех видов инъекций, особенно если злоумышленник подставит структуру SQL-запроса (например, "; DROP TABLE users;"). Кроме того, это не покрывает все особенности разных типов данных и не защищает от обхода фильтров через кодировку или спецсимволы. Нужно всегда использовать параметризованные запросы.


История

В одной из систем расчёта зарплат динамический SQL генерировал отчёты. Из-за неподдержки параметризации в старом фреймворке вручную склеивали строки. Один пользователь случайно (или не совсем) передал в поле "фамилия" фрагмент SQL — это позволило получить доступ к чужим зарплатам.

История

Малый интернет-магазин использовал динамический SQL для фильтрации товаров без должной валидации. При попытке указать нестандартное значение пользователь вызвал ошибку парсера SQL, что на время "положило" выдачу всех товаров.

История

В CRM буква “О'Коннор” вызвала ошибку в приложении, строящем SQL-запросы простым сложением строк. Из-за неэкранированной одинарной кавычки ни одна карточка с такой фамилией не сохранялась, что выявили только спустя год.