Внедрение структурированного языка запросов (SQLI) — это потенциально разрушительное использование уязвимости внедрения кода, специально нацеленной на язык запросов к базе данных SQL. Внедрение SQL — это результат передачи управляемых пользователем данных в виде запроса к серверной базе данных SQL. Неправильно закодированные формы позволят хакеру использовать их в качестве точки входа в базу данных, после чего данные в базе данных могут стать видимыми и возможен доступ к другим базам данных на том же сервере или другим серверам в сети.

Функции веб-сайта, такие как контактные формы, страницы входа в систему, функции поиска и любое поле, позволяющее пользователю вводить данные, подвержены атаке с внедрением SQL, поскольку сами поля, представленные для использования посетителем, ДОЛЖНЫ позволять, по крайней мере, некоторым командам SQL проходить непосредственно к сайту. база данных..

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

Любой динамический язык сценариев, включая ASP, ASP.NET, PHP, JSP и CGI, уязвим для атак. Единственное необходимое оборудование — это веб-браузер. В Интернете широко доступны инструменты, которые полуавтоматизируют процесс поиска слабых мест, и существует множество форумов, на которых хакеры делятся эксплойтами и помогают друг другу преодолевать препятствия.

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

Нетехнический пример SQL-инъекции

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

Wash <what should be washed> at <where should we wash> if <when should we wash?>

Пример заполнения формы

Wash dishes at the sink if the dishes are dirty.

Представьте себе сценарий, когда кому-то удается отправить эти инструкции:

Wash dishes at the sink and ignore remaining instructions. if the dishes are dirty.

Посудомоечная машина полностью автоматизирована. Делает точно так, как указано: моет посуду в раковине, даже если посуда уже чистая. Такая инъекция возможна из-за неправильного разделения структуры запроса и предоставленных данных. Автоматизированная посудомоечная машина не различает инструкции и данные; он просто анализирует все, что ему подается.

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

Технический пример внедрения SQL

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

Например, предположим, что функция веб-приложения генерирует строку со следующим оператором SQL:

SELECT * FROM users WHERE username = 'steve' AND password = 'mysuperduperpassword';

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

Как вы могли заметить, оператор содержит несколько новых специальных символов:

  • *(звездочка) — указание базе данных SQL вернуть все столбцы для выбранной строки базы данных.
  • =(equals) указывает базе данных SQL возвращать только те значения, которые соответствуют искомой строке.
  • (одинарная кавычка) используется для указания базе данных SQL, где начинается или заканчивается строка поиска.

Теперь рассмотрим следующий пример, в котором пользователь веб-сайта может изменить значения ‘$user’ и ‘$password’, например, в форме входа:

SELECT * FROM users WHERE username = '$user' AND password = '$password';

Злоумышленник может легко вставить любой специальный синтаксис SQL внутрь оператора, если приложение не санирует входные данные:

SELECT * FROM users WHERE username = 'admin'; -- ' AND password = 'anything';

Что здесь происходит? (admin’;- -) — это ввод злоумышленника, который содержит два новых специальных символа:

  • ; (точка с запятой) используется для указания парсеру SQL, что текущая инструкция завершена (в большинстве случаев не требуется)
  • --(двойной дефис) указывает синтаксическому анализатору SQL, что остальная часть строки является комментарием и не должна выполняться.

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

Смягчение SQLI

Параметризированные операторы
Многие языки программирования, используемые для создания веб-серверов, подключающихся к базе данных SQL, используют драйвер базы данных. Особенностью многих таких драйверов является то, что они имеют возможность принимать пользовательский ввод в качестве параметра, а не использовать пользовательские данные явно. Другими словами, использование параметризации пользовательских данных сообщает драйверу и, в свою очередь, базе данных SQL, что пользовательский ввод следует рассматривать только как данные, а не как команду запроса. Это гарантирует, что независимо от того, что пользователь отправляет в качестве ввода, это не будет рассматриваться как допустимая команда. Параметризованные операторы являются лучшей защитой от атак путем внедрения кода SQL, и их следует использовать всегда, когда они доступны. Чтобы лучше объяснить, что подразумевается под параметризацией, приведем два примера, написанных на всеми любимом языке JavaScript (пакет node-sql).

connection.query(
 ‘select * from users where email = ?’,
 [email],
 function(err, rows, fields) {
 // Do something with the retrieved data.
 });

Как видно из приведенного выше примера, данные для электронной почты предоставляются в запросе в виде вопросительного знака ?, а следующим параметром, передаваемым функции connection.query , является [email]. . Это говорит функции connection.query заменить ? на переменную с названием email и обрабатывать данные в электронной почте только как данные, а не интерпретировать данные как команды.

 connection.query(
 “select * from users where email =’” + email + “‘“,
 function(err, rows, fields) {
 // Do something with the retrieved data.
 });

В этом примере переменная email вводится прямо в сам запрос, не сообщая функции connection.query, что такое данные, а что команда. Таким образом, если пользователь сможет манипулировать своим вводом, он сможет добавить свои собственные команды в переменную электронной почты и, таким образом, разрешить внедрение SQL.

Очистка входных данных
Менее надежный метод предотвращения SQL – экранирование или очистка специальных символов, которые могут быть интерпретированы как команды. Цель атак с внедрением — преждевременное закрытие строки аргумента, поэтому символы «или» часто являются частью атак с внедрением SQL.
Экранирование символьных символов — это простой и легкий способ предотвратить все типы внедрения кода, и многие языки имеют встроенные функции, которые облегчают это для программиста. Есть только несколько соображений, которые необходимо учитывать.

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

У программиста также есть возможность комплексно очищать вводимые пользователем данные. Это может включать ряд регулярных выражений, предназначенных для обнаружения подозрительных строк символов, или, что еще проще, может использоваться для ограничения разрешенных символов в поле (разрешение только буквенно-цифровых символов для имени пользователя и блокирующих символов и т. д.).

Брандмауэр веб-приложений
Даже при соблюдении рекомендаций могут возникнуть новые уязвимости или непредвиденные сценарии, которые могут привести к внедрению кода. Брандмауэр веб-приложений — полезный инструмент для фильтрации SQLI и других типов атак с внедрением кода. Большинство современных WAF представляют собой интегрированные решения, дополняющие эвристики обнаружения и блокировки. Например, если WAF обнаруживает входные данные, которые выглядят подозрительно, но могут не быть полностью вредоносными, WAF может перекрестно ссылаться на репутацию/историю входящего IP-адреса, чтобы принять решение о блокировке запроса. Это помогает защитить сайты от возможных атак нулевого дня, на устранение которых у внутренних разработчиков обычно уходят недели, месяцы или годы.

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