Инъекции SQL являются одним из самых распространенных и основных видов кибератак. К сожалению, SQL-инъекция также является одной из самых разрушительных угроз, с которыми может столкнуться приложение. Эти атаки регулярно приводят к потере данных и особенно опасны для инфраструктур с общими базами данных.
В этой статье рассказывается о том, как предотвратить инъекции SQL. Читайте дальше, чтобы узнать, что такое SQL-инъекции, как работают эти атаки и какие шаги предпринимают компании для защиты своих баз данных от вредоносных инъекций.
- Что такое атака SQL Injection?
- Как работает SQL-инъекция?
- Типы SQL-инъекций
- Внутриполосный SQLi (классический SQLi)
- SQLi на основе ошибок
- SQLi на основе объединения
- Инференциальный SQLi (Blind SQLi)
- Слепой SQLi на основе содержимого
- Слепой SQLi на основе времени
- Внеполосный SQLi
- Как можно обнаружить SQL-инъекцию?
- Как предотвратить атаки SQL Injection?
- Санирование ввода
- Параметризованный SQL-код
- Ограничение прав доступа пользователей
- Настройка брандмауэра
- Обновления и исправления
- Регулярное тестирование
- Никогда не храните конфиденциальные данные в виде обычного текста
- Не показывайте ошибки базы данных пользователям
- Несмотря на опасность, атаки SQLi легко предотвратить
Что такое атака SQL Injection?
SQL-инъекция (SQLi) - это кибератака, при которой хакер запускает вредоносные SQL-запросы через приложение для манипулирования базой данных. Эти атаки могут затронуть любой веб-сайт или веб-приложение, которое опирается на базу данных SQL (MySQL, Oracle, Sybase, Microsoft SQL Server, Access, Ingres и т.д.).
Наша шпаргалка по командам MySQL предлагает обзор наиболее важных команд, необходимых для освоения этой РСУБД.
Последствия SQLi варьируются от легких до серьезных. После инъекции хакер может:
- Повредить, украсть или удалить данные.
- Получить root-доступ к системе.
- Создать новые записи, чтобы открыть дверь для более сложных взломов, таких как APT-атака.
- Повысить привилегии для доступа к другим приложениям и системам в сети.
- Скомпрометировать сервер или другую внутреннюю инфраструктуру.
- Запустить DDoS-атаку (отказ в обслуживании).
- Получить доступ к операционной системе через сервер базы данных.
Степень ущерба зависит от возможностей злоумышленника. Жертва может столкнуться с чем угодно - от нескольких ошибок в базе данных до полного захвата веб-сервера.
Как работает SQL-инъекция?
Большинство веб-приложений требуют от пользователей предоставления учетных данных для подтверждения их личности и уровня доступа. Если подтвержденный пользователь запрашивает данные, приложение отправляет SQL-запрос в базу данных в форме запроса и возвращает запрошенные данные.
Если приложение имеет уязвимость SQLi, хакер может пропустить процесс аутентификации и вручную ввести SQL-запросы (или вредоносную полезную нагрузку) в базу данных. База данных не распознает угрозу и выполняет запрос так, как будто приложение отправляет запрос.
В отличие от некоторых видов кибератак, SQL-инъекция требует, чтобы целевая система имела уязвимость, которую можно использовать. Большинство недостатков возникает из-за отсутствия строгого разделения между программным кодом и вводимыми пользователем данными.
Хакеры обычно атакуют базы данных через приложение или веб-сайт. Однако некоторые более изощренные атаки направлены непосредственно на базу данных.
Типы SQL-инъекций
Существует два вида SQL-инъекций:
- Классический SQLi: атаки, при которых хакер посылает команды в базу данных и собирает результаты на выходе.
- Слепая SQLi: Нарушения, при которых хакер посылает команды в базу данных, но не собирает результаты непосредственно на выходе.
Ниже перечислены семь наиболее распространенных типов SQL-инъекций, с которыми может столкнуться предприятие.
Внутриполосный SQLi (классический SQLi)
Внутриполосная SQLi возникает, когда хакер использует один и тот же канал связи для запуска атаки и сбора результатов. Вот пример уязвимости внутриполосной инъекции в коде WordPress:
1 2 3 | global $wpdb; $title = $wpdb->get_var("select post_title from " . $wpdb->posts . " where ID=" . $_GET['id']); echo $title; |
Этот код имеет слабое место в SQLi, потому что пользовательский ввод в $_GET['id'] идет непосредственно в базу данных. Здесь нет никакой санации или экранирования, поэтому злоумышленник может отправлять команды непосредственно в базу данных и получать вывод обратно в браузер. Например, хакер может отправить:
- Команды SELECT, которые извлекают записи из базы данных.
- Команды INSERT, создающие новые учетные записи пользователей.
- Команды UPDATE, изменяющие существующие записи.
Внутриполосный SQLi является наиболее распространенным типом SQL-инъекции.
SQLi на основе ошибок
SQLi на основе ошибок - это техника внутриполосной инъекции, основанная на сообщениях об ошибках. Хакеры неоднократно проверяют приложение на наличие ошибок, чтобы собрать информацию о структуре базы данных.
SQL-инъекции на основе ошибок позволяют злоумышленнику извлекать данные, такие как имена таблиц и их содержимое, из видимых ошибок. В некоторых случаях SQL-инъекции на основе ошибок достаточно, чтобы хакер смог перечислить всю базу данных.
SQLi на основе объединения
SQLi на основе объединения - это внутриполосная инъекция, использующая уязвимости SQL-оператора UNION.
Команда UNION выполняет один или несколько дополнительных запросов SELECT и добавляет результат к исходному запросу. Злоумышленник может использовать расширенные результаты для получения данных из других таблиц базы данных.
SQLi, основанный на объединении, работает только в том случае, если исходный и новый запросы имеют одинаковое количество и тип данных столбцов.
Инференциальный SQLi (Blind SQLi)
В инференциальном SQLi веб-приложение не передает данные через прямой вывод. Вместо этого злоумышленник должен собрать информацию, отправляя полезную нагрузку и наблюдая за ней:
- Ответ веб-приложения.
- Поведение сервера базы данных.
- Различия в веб-странице.
Вот пример слепого SQLi:
1 2 | global $wpdb; $title = $wpdb->get_var("select post_title from " . $wpdb->posts . " where ID=" . $_GET['id']); |
Пользовательский ввод идет непосредственно в базу данных путем конкатенации переменной $_GET['id'] с запросом. Браузер никогда не отображает результат, но злоумышленник может собрать информацию о базе данных, анализируя реакцию сервера.
Этот тип инъекции требует больше времени на эксплуатацию, чем внутриполосный SQLi, но последствия не менее опасны.
Слепой SQLi на основе содержимого
SQLi на основе содержимого - это метод инференции, при котором злоумышленник заставляет базу данных возвращать различные результаты в зависимости от того, какой результат был получен в результате запроса - TRUE или FALSE.
Вот пример SQLi на основе содержимого:
1 2 3 | select post_status from wp_posts where ID=1 и (select 1 from wp_users where substring(user_pass,1,1) = 'a' и ID=1) |
Этот запрос проверяет, является ли первая буква хэшированного пароля пользователя с ID 1 буквой A. Хотя атакующий не видит результата, поведение веб-страницы показывает, верен запрос или нет. С помощью этой техники хакер может перебрать все символы и извлечь пароль администратора.
Контентные SQLi атаки медленны, особенно на большие базы данных. Атакующему приходится перечислять базу данных символ за символом. Другое название этого типа атаки - слепая SQL-инъекция на основе булевых функций.
Слепой SQLi на основе времени
SQLi на основе времени - это еще одна техника инференциальной инъекции. Злоумышленник посылает запросы, которые заставляют базу данных ждать (спать) в течение определенного количества секунд, прежде чем ответить.
Например, хакер может спросить базу данных, начинается ли первая буква учетной записи администратора с буквы А. Если первая буква А, хакер дает указание базе данных "заснуть" на 10 секунд. Вот как будет выглядеть такой код:
1 2 3 4 5 6 | select post_title from wp_posts where ID=1 union select IF( substring(wp_users.user_login,1,1)='a', BENCHMARK(10000000,ENCODE('blah','asdf')), null) from wp_users where ID=1 |
Хакер может не увидеть результат, но время отклика для создания веб-страницы позволяет понять ответ.
Как и SQLi, основанные на содержимом, инъекции, основанные на времени, являются медленными. К сожалению, эти атаки часто полностью автоматизированы, поэтому неправильные догадки не замедляют процесс.
Внеполосный SQLi
Внеполосный SQLi - это наименее распространенный тип инъекции, который обычно происходит, когда хакер не может осуществить прямую атаку "запрос-ответ". Вместо этого хакер создает SQL-запросы, которые заставляют базу данных создать соединение с внешним сервером, находящимся под контролем злоумышленника.
Сервер базы данных должен иметь возможность выполнять DNS- или HTTP-запросы для доставки данных злоумышленнику. В противном случае внеполосный SQLi не работает.
Злоумышленники обычно выбирают внеполосный подход в качестве альтернативы методам, основанным на времени, когда ответы сервера нестабильны.
Как можно обнаружить SQL-инъекцию?
Попытки SQLi часто выглядят как стандартные ошибки базы данных, поэтому инъекции трудно обнаружить без специальных инструментов. Однако ваша служба безопасности должна отслеживать признаки SQL-инъекций.
Каждая SQLi требует проб и ошибок. Хакеры обычно устанавливают червя или бота для многократного исследования веб-сайта на наличие дефектов. Настройте инструменты сканирования на отслеживание неудачных входов в систему и ошибок синтаксиса.
Вот дополнительные способы обнаружения SQL-инъекций:
- Изучите событие error_reported на предмет странных ошибок.
- Поиск в базе данных распространенных HTML-тегов, таких как http-equiv="refresh" или iframe.
- Отслеживайте трафик на предмет подозрительных изменений в поведении, особенно изменений в разрешениях и паролях.
- Настройте сетевую систему обнаружения вторжений (IDS) для мониторинга соединений с сервером базы данных.
- Установите IDS на хосте для мониторинга журналов веб-сервера.
Используйте инструменты оценки уязвимостей, чтобы убедиться, что ваше приложение защищено от SQLi и подобных кибератак.
Как предотвратить атаки SQL Injection?
Существует несколько эффективных мер, которые предприятие может предпринять для предотвращения атак SQLi.
Санирование ввода
Санирование ввода (или валидация) - это практика проверки и фильтрации вводимых пользователем данных. Эта техника гарантирует, что приложение сможет идентифицировать незаконные пользовательские вводы и опасные исполняемые файлы.
Разработчики могут обеззараживать вводимые данные тремя способами:
- Санирование по белому списку: Только предварительно одобренные символы и строки кода могут попасть в базу данных.
- Санирование черного списка: Разработчики запрещают определенным символам попадать в базу данных (перевод строки, лишние пробелы, теги, табуляции и т.д.).
- Escape sanitizing: Все данные в запросах требуют SQL-эскейпа перед выполнением запроса.
Как правило, белый список является более простым и безопасным вариантом, чем черный список. Умный хакер может найти способ обойти черный список, поэтому по возможности проверяйте пользовательский ввод с помощью белых списков.
Еще одна хорошая практика - проверка ввода пользователя с помощью выпадающих меню и радиокнопок. Такие поля ввода не позволяют пользователям вводить данные и предотвращают внедрение исполняемого кода.
Параметризованный SQL-код
Параметризованные запросы требуют от разработчиков сначала определить весь SQL-код, а затем передать каждый параметр в запрос. Такой стиль кодирования позволяет базе данных различать код и данные, что невозможно при использовании динамических SQL-запросов.
Параметризованный SQL-код не позволяет злоумышленникам изменить смысл запроса, даже если они вставляют команды. Например, если хакер введет идентификатор пользователя '1'='1, запрос будет искать имя пользователя, которое соответствует всей строке '1'='1. База данных не воспримет запрос как команду.
Ограничение прав доступа пользователей
Используйте систему безопасности Zero Trust и ограничьте пользователей минимальными разрешениями, необходимыми для выполнения их ролей. Чем меньше учетных записей с разрешениями на чтение-запись-исполнение, тем лучше.
Например, если веб-сайт возвращает содержимое базы данных только с помощью оператора SELECT, не предоставляйте подключению другие привилегии, такие как INSERT, UPDATE или DELETE.
Еще одна хорошая практика - не доверять всем пользовательским данным. Относитесь к вводу от внутренних пользователей так же, как и к вводу, поступающему из внешних и сторонних источников. Также никогда не позволяйте веб-приложению подключаться к базе данных с привилегиями администратора.
Настройка брандмауэра
Используйте брандмауэр веб-приложений (WAF) для фильтрации всего трафика между веб-приложениями и вашей базой данных. Брандмауэр защищает все веб-приложения, поэтому установите защиту, чтобы остановить SQLi и подобные кибератаки.
Обновления и исправления
Поддерживайте все системы и средства защиты в актуальном состоянии с помощью последних исправлений и обновлений. Это поможет:
Вылавливать новые ошибки, позволяющие осуществить SQL-инъекцию.
Предотвратить использование злоумышленниками слабых мест и ошибок, присутствующих в старых версиях программного обеспечения.
Регулярно обновлять все программные компоненты веб-приложений, включая библиотеки, плагины, фреймворки, веб-сервер и сервер баз данных.
Регулярное тестирование
Проводите тестирование безопасности для проверки устойчивости вашей базы данных и связанных с ней приложений. Регулярные тесты жизненно важны для обнаружения уязвимостей при любых кибератаках. Рассмотрите возможность проведения:
- Тесты динамического анализа (DAST), которые рассматривают приложение с точки зрения злоумышленника.
- Тесты статического анализа (SAST), которые ищут уязвимости на уровне кода.
Ручные тесты на потенциальные точки входа в приложение также помогают обнаружить уязвимости SQLi. Вот несколько тестов, которые следует рассмотреть:
- Вводите символы одинарных кавычек и проверяйте ответы базы данных.
- Выполните булевы условия (OR 1=1, OR 1=2 и т.д.) и посмотрите на различия в ответах.
- Отправьте полезную нагрузку, которая вызывает временную задержку при выполнении. Измерьте разницу во времени отклика.
- Запустите полезную нагрузку OAST, которая вызывает внеполосное сетевое взаимодействие. Отслеживайте результирующее взаимодействие на предмет потенциальных эксплойтов.
Никогда не храните конфиденциальные данные в виде обычного текста
Шифруйте все частные и конфиденциальные данные в вашей базе данных. Шифрование также обеспечивает дополнительный уровень защиты, если злоумышленнику удастся перехватить конфиденциальные данные.
Не показывайте ошибки базы данных пользователям
Сообщения об ошибках базы данных никогда не должны отображаться в веб-браузере клиента. Злоумышленник может использовать технические детали из сообщений об ошибках для корректировки запросов с целью успешной инъекции.
Вместо того чтобы отображать сообщения об ошибках с полезной информацией, установите простые словесные сообщения об ошибках, извиняющиеся за причиненные неудобства.
Обучение и поддержание осведомленности о SQLi
Предотвращение SQL-инъекций - это командная работа, и все сотрудники должны знать о важности кибербезопасности. Проведите соответствующее обучение по безопасности для всех разработчиков, сотрудников QA, системных администраторов и DevOps.
Несмотря на опасность, атаки SQLi легко предотвратить
Хотя SQL-инъекции могут быть опасны, хорошо организованная компания никогда не станет жертвой этих атак. Примите надлежащие меры предосторожности и убедитесь, что ваши базы данных устойчивы к SQL-инъекциям.