Что такое ExtractValue и почему она опасна?

Функция ExtractValue в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Однако из-за особенностей обработки ошибок она стала популярным инструментом для проведения error-based SQL-инъекций. Злоумышленники могут внедрять в запросы конструкции, которые вызывают ошибки с полезной информацией, например, такой как %" ) OR EXTRACTVALUE(2759,CONCAT(0x7e,((SELECT (ELT(2759=2759,1)))),0x7e))-- -. В этой статье мы разберём, как работает эта атака, какие данные можно получить и как защититься.

Синтаксис и принцип работы ExtractValue

Функция имеет следующий синтаксис:

EXTRACTVALUE(XML_document, XPath_expression)

Она возвращает текст из XML-документа, соответствующий XPath-выражению. Если XPath-выражение некорректно или не соответствует ни одному узлу, MySQL генерирует ошибку с сообщением, содержащим часть переданного XPath. Именно это свойство используется в атаках: злоумышленник может внедрить в XPath результат подзапроса, и если вызвать ошибку, то в сообщении об ошибке отобразится результат.

Пример простой инъекции

Рассмотрим классический пример. Пусть уязвимый запрос выглядит так:

SELECT * FROM users WHERE id = '$input';

Если передать в $input значение 1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -, то при выполнении возникнет ошибка вида:

XPATH syntax error: '~5.7.23~'

Таким образом, злоумышленник получает версию СУБД. Аналогично можно извлечь имена таблиц, колонок и сами данные.

Разбор запроса из примера

В запросе %" ) OR EXTRACTVALUE(2759,CONCAT(0x7e,((SELECT (ELT(2759=2759,1)))),0x7e))-- - используется несколько трюков:

  • %" ) — закрытие кавычки и скобки, чтобы разорвать оригинальный запрос.
  • OR EXTRACTVALUE(...) — добавляет условие, которое всегда ложно или истинно, но главное — вызывает функцию ExtractValue.
  • CONCAT(0x7e, ..., 0x7e) — объединяет тильды (~) с результатом подзапроса, чтобы облегчить поиск в сообщении об ошибке.
  • ELT(2759=2759,1) — функция ELT возвращает N-й элемент из списка. Здесь условие 2759=2759 всегда истинно (1), поэтому ELT возвращает 1. Это простейший пример, но на практике вместо 1 может быть подзапрос, извлекающий данные.
  • -- - — комментарий, обрезающий остаток оригинального запроса.

В результате MySQL попытается вычислить XPath-выражение, содержащее результат подзапроса, и выдаст ошибку с внедрёнными данными.

Какие данные можно извлечь?

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

  • Версию MySQL/MariaDB
  • Имя текущей базы данных
  • Список таблиц и колонок
  • Логины и пароли пользователей
  • Другие конфиденциальные данные

Важно отметить, что длина выводимой строки ограничена (обычно 32 символа), поэтому для получения больших объёмов данных используются посимвольные или постраничные методы.

Ограничения и особенности

Функция ExtractValue доступна в MySQL и MariaDB. В новых версиях (начиная с MySQL 8.0) она помечена как устаревшая, но продолжает работать. Также существуют аналоги: UpdateXML, который действует схожим образом.

Следует учитывать, что для успешной эксплуатации необходимо, чтобы веб-приложение выводило сообщения об ошибках СУБД пользователю. Если ошибки подавляются, атака может не сработать, и тогда используются слепые методы (blind SQLi).

Как защититься от error-based SQL-инъекций?

Основной метод защиты — использование параметризованных запросов (prepared statements). Они разделяют код и данные, поэтому внедрение SQL-кода становится невозможным. Дополнительные меры:

  • Экранирование специальных символов (но это менее надёжно).
  • Ограничение привилегий пользователя базы данных, от имени которого работает приложение.
  • Отключение вывода подробных ошибок СУБД в production-среде.
  • Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов.
  • Регулярное обновление СУБД и фреймворков.

Также рекомендуется проводить аудит кода и пентесты для выявления уязвимостей.

Заключение

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

Источники