Что такое EXTRACTVALUE и при чём тут SQL-инъекции

Функция EXTRACTVALUE — это встроенная функция СУБД MySQL (а также Oracle), предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_фрагмент, XPath_выражение). Она принимает два строковых аргумента: фрагмент XML-разметки и локатор XPath, а возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента, соответствующего XPath.

Однако злоумышленники часто используют эту функцию в атаках типа SQL-инъекция, основанная на ошибках (error-based SQL injection). Суть в том, что при передаче некорректного XPath-выражения MySQL генерирует ошибку, в тексте которой может отображаться результат подзапроса. Это позволяет атакующему извлекать данные из базы.

Разбор конкретного запроса

Рассмотрим строку, которая часто встречается в эксплойтах: ')) AND EXTRACTVALUE(5859,CONCAT(0x7e,((SELECT (ELT(5859=5859,1)))),0x7e))-- -. Это фрагмент, который внедряется в уязвимый параметр приложения. Разберём его по частям.

  • ')) — закрывает ранее открытые скобки и кавычки в оригинальном SQL-запросе, чтобы внедрить свой код.
  • AND EXTRACTVALUE(5859, ...) — добавляет условие, которое всегда истинно (если подзапрос вернёт 1), но при этом вызывает функцию EXTRACTVALUE с заведомо некорректным первым аргументом (число 5859 не является XML).
  • CONCAT(0x7e, ((SELECT (ELT(5859=5859,1)))), 0x7e) — формирует строку для второго аргумента. 0x7e — это тильда (~), используется как разделитель, чтобы облегчить поиск результата в сообщении об ошибке. ELT(5859=5859,1) — функция ELT возвращает N-й элемент из списка; здесь условие 5859=5859 истинно (равно 1), поэтому возвращается 1. Фактически это заглушка, которая может быть заменена на любой подзапрос для извлечения данных.
  • -- - — комментарий, обрезающий остаток оригинального запроса.

При выполнении такого запроса MySQL попытается обработать число 5859 как XML, что невозможно, и выдаст ошибку вида: XPATH syntax error: '~1~'. Атакующий видит эту ошибку и понимает, что инъекция работает. В реальной атаке вместо ELT(5859=5859,1) подставляются подзапросы, извлекающие имена таблиц, колонок или хеши паролей.

Почему EXTRACTVALUE становится инструментом атаки

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

По данным исследователей безопасности, error-based SQL-инъекции через XPATH — один из самых надёжных способов получения информации, когда UNION-инъекции невозможны.

Пример эксплуатации

Предположим, уязвимый запрос выглядит так:

SELECT * FROM users WHERE id = '1'

Атакующий подставляет:

1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -

В ответе сервера появится ошибка: XPATH syntax error: '~5.7.33~'. Так узнаётся версия СУБД. Далее можно извлекать имена таблиц через information_schema и так далее.

Защита от SQL-инъекций через EXTRACTVALUE

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

  • Отключить вывод подробных ошибок СУБД в production-среде.
  • Использовать ORM или библиотеки, автоматически экранирующие опасные символы.
  • Проводить регулярные сканирования уязвимостей и пентесты.
  • Ограничить права пользователя базы данных, чтобы даже при инъекции нельзя было прочитать системные таблицы.

Важно понимать, что EXTRACTVALUE — не единственная функция, используемая в error-based атаках. Аналогично применяются UpdateXML, GeometryCollection и другие. Но принцип остаётся тем же: вызвать ошибку, содержащую полезные данные.

Заключение

Запрос ')) AND EXTRACTVALUE(5859,CONCAT(0x7e,((SELECT (ELT(5859=5859,1)))),0x7e))-- - — это классический пример эксплойта для проверки наличия SQL-инъекции через функцию EXTRACTVALUE. Он демонстрирует, как злоумышленники могут использовать штатные возможности СУБД для извлечения информации. Понимание этого механизма помогает разработчикам и специалистам по безопасности правильно выстраивать защиту.

Источники