Burp Suite. SQL Injection: Обнаружение & Предотвращение

3 мин
Автор PINTA IT
Burp Suite. SQL Injection: Обнаружение & Предотвращение

Большинство уязвимостей SQL-инъекций можно быстро и надежно обнаружить с помощью сканера веб-уязвимостей Burp Suite.

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

  • Отправка символа одинарной кавычки ' и поиск ошибок или других аномалий.
  • Отправка некоторого специфичного для SQL синтаксиса, который оценивает базовое (исходное) значение точки входа и другое значение, и поиск систематических различий в полученных ответах приложения.
  • Отправка логических условий, таких как OR 1 = 1 и OR 1 = 2, и поиск различий в ответах приложения.
  • Отправка полезных данных, предназначенных для запуска временных задержек при выполнении в запросе SQL, и поиск различий во времени, необходимом для ответа
  • Отправка полезных нагрузок OAST, предназначенных для запуска внеполосного сетевого взаимодействия при выполнении в запросе SQL, и отслеживания любых возникающих взаимодействий.

SQL-инъекция в разных частях запроса

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

Но уязвимости в SQL-инъекциях в принципе могут возникать в любом месте запроса и в разных типах запросов. Наиболее распространенные места, где возникает SQL-инъекция:

  • В операторах UPDATE, в обновленных значениях или в предложении WHERE.
  • В операторах INSERT, внутри вставленных значений.
  • В операторах SELECT, внутри имени таблицы или столбца.
  • В операторах SELECT, в предложении ORDER BY.

SQL-инъекция второго порядка

SQL-инъекция первого порядка возникает, когда приложение принимает пользовательский ввод из HTTP-запроса и в процессе обработки этого запроса небезопасным образом вводит ввод в SQL-запрос.

В SQL-инъекции второго порядка (также известной как хранимая SQL-инъекция) приложение берет пользовательский ввод из HTTP-запроса и сохраняет его для будущего использования. Обычно это делается путем помещения входных данных в базу данных, но никакой уязвимости в том месте, где хранятся данные, не возникает. Позже, при обработке другого HTTP-запроса, приложение извлекает сохраненные данные и небезопасным образом вводит их в SQL-запрос.

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

Факторы, специфичные для базы данных

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

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

  • Синтаксис для конкатенации строк.
  • Комментарии.
  • Пакетные (или сложенные) запросы.
  • Платформо-зависимые API.
  • Сообщения об ошибках.

Read more SQL injection cheat sheet

Как предотвратить SQL-инъекцию

Большинство случаев внедрения SQL можно предотвратить с помощью параметризованных запросов (также называемых подготовленными операторами) вместо конкатенации строк в запросе.

Следующий код уязвим для внедрения SQL, потому что пользовательский ввод объединяется непосредственно в запрос:

String query = "SELECT * FROM products WHERE category = '"+ input + "'";

Statement statement = connection.createStatement();

ResultSet resultSet = statement.executeQuery(query);

Этот код можно легко переписать так, чтобы пользовательский ввод не влиял на структуру запроса:

PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");

statement.setString(1, input);

ResultSet resultSet = statement.executeQuery();

Параметризованные запросы могут использоваться для любой ситуации, когда ненадежный ввод отображается как данные в запросе, включая предложение WHERE и значения в выражении INSERT или UPDATE. Их нельзя использовать для обработки ненадежного ввода в других частях запроса, таких как имена таблиц или столбцов или предложение ORDER BY. Функциональные возможности приложения, которые помещают ненадежные данные в эти части запроса, должны будут использовать другой подход, такой как допустимые значения белого списка или использование другой логики для обеспечения требуемого поведения.

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

Как предотвратить слепые SQL-атаки?

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

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