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

Вот пример. Предположим, приложение использует следующий запрос на получение чьих-либо учётных данных:

SELECT USERNAME,PASSWORD from USERS where USERNAME='<username>' AND PASSWORD='<password>';

Здесь имя пользователя username и пароль password — это данные, вводимые пользователем. Допустим, злоумышленник в оба поля введёт ' OR '1'='1. SQL-запрос будет выглядеть так:

SELECT USERNAME,PASSWORD from USERS where USERNAME='' OR '1'='1' AND PASSWORD='' OR '1'='1';

На запрос приходит true, и доступ получен. Это пример самой простой SQL-инъекции.

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

Примечание: пример максимально упрощён и приводится здесь исключительно в ознакомительных целях. В реальной жизни таких случаев практически не найти.

Можете заглянуть в эту шпаргалку и узнать, как выполнять запросы в базы данных SQL разных поставщиков.

Как нащупать уязвимость?

В большинстве случаев уязвимость обнаруживается введением неверных параметров, например: ''' a' or 1=1--"a"" or 1=1--"or a = aa' waitfor delay '0:0:10'--1 waitfor delay '0:0:10'--%26' or username like '% и т.д. После чего проявляются изменения в поведении приложения.

Можно проанализировать длину ответа сервера и время, требующееся для отправки этого ответа. Такая полезная нагрузка, как 'a' or 1=1-- и т.д., может свидетельствовать об изменениях в ответе сервера баз данных. Но в случае отсутствия изменений мы можем попробовать запустить задержки по времени, используя полезную нагрузку a' waitfor delay '0:0:10'--. Так можно задержать отправку ответа сервера на определённое время.

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

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

Количество столбцов можно определить командой order by. Например:

www.onlineshopping.com/products.php?pid=8 order by 1 -- //
www.onlineshopping.com/products.php?pid=8 order by 2 -- //// Если параметр - строка, то надо добавить после него значок «'».www.onlineshopping.com/products.php?usr=b' order by 3 -- //
www.onlineshopping.com/products.php?usr=a' order by 4 -- //

Комментарии в SQL начинаются вот с такой комбинации символов --. Чтобы сохранить пробел после --, просто добавляем любой символ: так пробел не будет игнорироваться в HTTP-запросе. Для комментариев могут использоваться также # или /* */ в зависимости от поставщика базы данных SQL.

Продолжаем этот процесс, пока не появится ошибка. Если ошибка случилась во время использования полезной нагрузки order by 5, а не order by 4, значит, запрос возвращает 4 столбца.

Как использовать уязвимости

Обнаружив уязвимость приложения и определив количество столбцов, попробуем найти необходимую информацию о базе данных (БД): имя БДимя пользователя БДверсия БДимена таблицимена столбцов той или иной таблицы и т.д. Загляните в шпаргалку по инъекциям в SQL: там есть соответствующие запросы.

Типы SQL-инъекций

  1. На основе ошибки: этот тип SQL-инъекции использует сообщения об ошибке, выбрасываемой сервером базы данных. Такие сообщения могут дать полезную информацию о структуре базы данных.
  2. С использованием UNION: эта техника задействует оператор SQL UNION для объединения результатов двух запросов SELECT в единую таблицу. Так злоумышленник может получить информацию из других таблиц добавлением результатов к исходному запросу, выполненному в базу данных.
  3. «Слепая» инъекция: имеет место, когда приложение подвержено SQL-инъекции, но результаты SQL-запроса не возвращаются в HTTP-ответе. В этом случае в базу данных выполняется запрос на любой из операторов true/false, и отслеживаются изменения для условий true и false. Этот тип подразделяется на два подтипа:
  4. а) На основе данных в ответе сервера: здесь на сервер базы данных выполняется запрос с любым условным оператором, а ответ от сервера анализируется на наличие расхождений при отправке условия true и false.
  5. б) С использованием времени ответа сервера: эта техника основана на добавлении SQL-запроса, который замедляет базу данных на определённое время в зависимости от указанного условия. Будет запрос true или false — зависит от времени ответа сервера.
  6. С использованием особенностей сервера: редкий тип SQL-инъекции, зависит от конкретных характеристик сервера базы данных. Использует способность сервера базы данных выполнять веб-запросы типа HTTPDNS и ftp для отправки данных злоумышленнику.

Как защитить код от SQL-инъекции?

  1. Никогда не формируйте запрос непосредственно из пользовательских данных. Делайте это через параметризованные запросы. Онисоздают условия для того, чтобы данные, добавляемые в SQL-запросы, были в безопасности.
  2. Не будет лишним очистить данные перед сохранением в базе данных. Ну и нужно провести проверку вводимых данных: например, в имени не должно быть цифр, а в номере телефона — букв. Хотя и такие меры защиты не всегда помогают.
  3. Используйте безопасный драйвер для взаимодействия с БД SQL, такие как SQLAlchemy для Python, автоматически предотвращающие все атаки с применением SQL-инъекции.

Полезные ссылки

  1. SQL Map — инструмент с открытым исходным кодом, который автоматизирует процесс выявления и использования уязвимостей типа SQL-инъекций.
  2. Репозиторий с целой кучей информации по SQL-инъекциям. Здесь можно найти шпаргалки и полезные нагрузки, которые пригодятся в самых разных ситуациях.

Читайте также:

Перевод статьи Ashwin GoelA Beginner’s Guide to SQL Injection

Предыдущая статья8 незаменимых веб-приложений для разработчиков
Следующая статьяЧто такое *args и **kwargs в Python?