Это пятая статья из серии, посвященной производительности MySQL. Эта статья изначально опубликована на https://www.learncsdesign.com

Не позволяйте пользователям вводить код, но разрешайте им вводить значения.

Веб-разработчики видят множество вещей, которые могут нанести вред создаваемым ими приложениям. Одна из таких атак нацелена на вашу базу данных и хранящиеся в ней данные — SQL-инъекция. Распространенной целью такой атаки является эксфильтрация конфиденциальных данных из базы данных для личной выгоды. Разработчики упускают из виду важность безопасности при создании общедоступных веб-решений, поэтому эта атака так распространена и опасна.

Что такое SQL-инъекция?

Атака с внедрением SQL включает в себя внедрение SQL-запросов в приложение через входные данные от клиента. Эксплойты SQL-инъекций могут считывать конфиденциальные данные базы данных, изменять данные базы данных (вставлять/обновлять/удалять), выполнять административные операции с базой данных (например, отключение СУБД) и в некоторых случаях отдавать команды операционной системе. При атаках с внедрением SQL команды SQL вводятся во входные данные плоскости данных для выполнения предопределенных команд SQL.

Как работает SQL-инъекция?

Уязвимость SQL Injection возникает, когда разработчики программного обеспечения создают динамические запросы к базе данных на основе конкатенации строк, включающих пользовательский ввод. Атака с внедрением SQL в основном работает, помещая все, что пользователь пишет в поле ввода, в запрос и передавая его в базу данных.

Ошибок SQL-инъекций можно легко избежать. Для разработчиков есть два варианта:

  • Прекратите писать динамические запросы, которые объединяют строки; и/или
  • Убедитесь, что пользовательский ввод, содержащий вредоносный SQL, не влияет на логику запроса.

Антипаттерн: выполнять непроверенный ввод как код

Внедрение SQL происходит, когда вы интерполируете некоторый контент в строку запроса SQL и изменяет синтаксис вашего запроса способами, которые вы не планировали. Как и в классическом примере внедрения SQL, значение, интерполированное в вашу строку, завершает оператор SQL и выполняет второй завершенный оператор.

Например, если «bugId» равен 1234; DELETE FROM bugs, результирующий SQL будет выглядеть следующим образом:

SELECT * FROM bugs WHERE bug_id = 1234; DELETE FROM bugs

Все ошибки будут удалены из таблицы ошибок.

Когда злоумышленник может манипулировать вашими операторами SQL, внедрение SQL становится более опасным. Например, ваше приложение может разрешить пользователям изменять свои пароли.

Ваш оператор SQL может быть использован хитрым злоумышленником, который знает, как используются параметры запроса.

UPDATE accounts SET password_hash = SHA2('securepassword') WHERE account_id = 123 or TRUE;

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

Изменяя синтаксис оператора SQL до его анализа, SQL Injection работает. Вы рискуете SQL-инъекцией, если вставите динамические части до того, как оператор будет проанализирован.

Первичная защита

* Вариант 1: Подготовленные отчеты (с параметризованными запросами)

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

* Вариант 2: хранимые процедуры

Хранимая процедура — это еще один метод, который, по мнению многих разработчиков программного обеспечения, защищает от уязвимостей SQL Injection. Хранимые процедуры обычно содержат фиксированные операторы SQL, анализируемые при их определении. Однако динамический SQL может использоваться в хранимых процедурах небезопасным образом. Динамический SQL в хранимых процедурах так же безопасен, как динамический SQL в коде приложения.

* Вариант 3: Проверка ввода в белый список

Недопустимо использовать переменные связывания в определенных частях SQL-запросов, таких как имена таблиц и столбцов и индикаторы порядка сортировки (ASC или DESC). Лучшая защита в таких случаях — проверка входных данных или изменение дизайна запроса.

* Вариант 4: экранирование всех введенных пользователем данных

Запросы SQL можно защитить от случайных несовпадающих символов кавычек, экранируя любые символы кавычек, чтобы они не становились концом строки в кавычках. Стандартный SQL позволяет вам сделать буквальный символ кавычек, используя два символа кавычек.

SELECT * from department where department_name='O''mega';

В большинстве баз данных следующий символ кавычки также можно экранировать с помощью обратной косой черты.

SELECT * from department where department_name='O\'mega';

Принципы работы для предотвращения SQL-инъекций

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

Вы не можете защитить свой код SQL с помощью одного метода. Все вышеперечисленные методы следует изучить и использовать надлежащим образом.

Рекомендации по проверке кода для SQL-инъекций

  • Найдите операторы SQL, сформированные с использованием переменных приложения, конкатенации строк или замен.
  • Все динамическое содержимое, используемое в ваших операторах SQL, должно быть прослежено до его источника. Ищите данные из внешнего источника, включая пользовательский ввод, файлы, среду, веб-службы, сторонний код или даже строку базы данных.
  • Любой внешний контент следует рассматривать как потенциально опасный. Фильтры, валидаторы и массивы сопоставления можно использовать для преобразования ненадежного контента.
  • Используйте надежные функции экранирования или параметры запроса, чтобы интегрировать внешние данные в ваши операторы SQL.
  • Проверьте свои хранимые процедуры и другие места, где можно найти динамические операторы SQL.

Если вам понравился пост, не забудьте похлопать. Если вы хотите подключиться, вы можете найти меня в LinkedIn.

Рекомендации

Книга: SQL Antipatterns
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html