Что такое EXTRACTVALUE и при чём тут SQL-инъекции?
Функция EXTRACTVALUE в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Однако при неправильной обработке пользовательского ввода эта функция может стать мощным инструментом для проведения error-based SQL-инъекций (SQLi, основанных на ошибках).
Суть атаки: если злоумышленник может внедрить произвольный SQL-код в запрос, он вызывает EXTRACTVALUE с заведомо некорректным XPath, содержащим результат подзапроса. MySQL генерирует ошибку, в тексте которой отображается переданное значение. Так злоумышленник получает данные из базы (версию СУБД, имена таблиц, логины, пароли) прямо в сообщении об ошибке.
Разбор конкретного payload'а
Рассмотрим строку из запроса: ` AND EXTRACTVALUE(7730,CONCAT(0x7e,((SELECT (ELT(7730=7730,1)))),0x7e))-- -. Это классический пример error-based инъекции через EXTRACTVALUE.
- ` — обратная кавычка, закрывающая предполагаемое строковое значение в уязвимом параметре.
- AND — логический оператор, присоединяющий вредоносное условие.
- EXTRACTVALUE(7730, ...) — первый аргумент — произвольное число (7730), второй — XPath-выражение, которое заведомо вызовет ошибку.
- CONCAT(0x7e, ((SELECT (ELT(7730=7730,1)))), 0x7e) — формирует строку, состоящую из символа
~(0x7e), результата подзапроса и ещё одного~. ПодзапросSELECT (ELT(7730=7730,1))возвращает 1, так как условие 7730=7730 истинно. ELT(N, str1, str2, ...) возвращает N-ю строку из списка; здесь N=1, поэтому возвращается 1. - -- - — комментарий, обрезающий остаток оригинального запроса.
В результате MySQL попытается выполнить EXTRACTVALUE с XPath, содержащим символ ~, что недопустимо, и выдаст ошибку вида: XPATH syntax error: '~1~'. Вместо «1» мог бы быть любой другой результат подзапроса — например, версия базы или имя пользователя.
Почему это работает?
Функция EXTRACTVALUE при обнаружении недопустимого символа в XPath-выражении генерирует ошибку, в тексте которой указывает проблемный фрагмент. Злоумышленник конкатенирует к этому фрагменту данные, полученные из подзапроса. Таким образом, содержимое базы данных «утекает» через сообщение об ошибке, которое часто отображается на странице или возвращается в HTTP-ответе.
Важно: для успешной эксплуатации приложение должно выводить ошибки СУБД пользователю. В противном случае атака не сработает.
Этот метод относится к классу error-based SQL-инъекций и часто используется, когда другие техники (UNION, blind) недоступны или менее удобны.
Какие данные можно извлечь?
С помощью EXTRACTVALUE можно получить практически любую информацию, которую возвращает подзапрос:
- версию MySQL (
SELECT version()); - имя текущего пользователя (
SELECT user()); - имя базы данных (
SELECT database()); - список таблиц и колонок через
information_schema; - конкретные данные (логины, хеши паролей, номера карт).
Ограничение — длина выводимой строки. MySQL обрезает сообщение об ошибке, поэтому длинные значения приходится извлекать по частям, используя SUBSTRING и LIMIT.
Как защититься от EXTRACTVALUE-инъекций?
Основной метод — не допускать попадания пользовательского ввода в SQL-запрос без обработки. Рекомендации:
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ, так как данные и код разделяются на уровне драйвера.
- Применяйте ORM. Современные ORM (Hibernate, Entity Framework, Eloquent) автоматически экранируют параметры.
- Валидируйте входные данные. Если параметр ожидается числовым, приводите его к числу; если строковым — ограничивайте допустимые символы.
- Отключайте вывод ошибок СУБД в production. Настройте
display_errors = Offв PHP или используйте кастомные страницы ошибок. Это лишает атакующего обратной связи. - Ограничьте права пользователя БД. Не используйте root для веб-приложений; давайте только необходимые привилегии.
- Установите WAF (Web Application Firewall). Он может блокировать подозрительные запросы, содержащие EXTRACTVALUE, CONCAT с 0x7e и т.п.
Также рекомендуется регулярно обновлять СУБД и фреймворки — в новых версиях некоторые функции могут быть удалены или изменены для снижения рисков.
Заключение
EXTRACTVALUE — удобная функция для работы с XML, но при небрежном обращении с пользовательским вводом она превращается в инструмент атаки. Error-based SQL-инъекции через EXTRACTVALUE позволяют быстро извлекать данные из базы, если приложение выводит ошибки. Единственная надёжная защита — параметризация запросов и сокрытие деталей ошибок от конечного пользователя.
Комментарии
—Войдите, чтобы оставить комментарий