Что такое ExtractValue в MySQL

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

Например, запрос SELECT EXTRACTVALUE('<a><b>текст</b></a>', '/a/b') вернёт строку «текст». Эта функция часто используется в приложениях, где данные хранятся в формате XML, и требуется быстро получить нужное значение без парсинга на стороне клиента.

Error-based SQL-инъекция через ExtractValue

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

Классический пример полезной нагрузки, подобной той, что приведена в запросе пользователя:

%')) AND EXTRACTVALUE(6263,CONCAT(0x7e,((SELECT (ELT(6263=6263,1)))),0x7e))-- -

Здесь EXTRACTVALUE вызывается с первым аргументом 6263 (произвольное число, играющее роль идентификатора), а вторым — выражение CONCAT(0x7e, (SELECT ...), 0x7e). Символ 0x7e — это тильда (~), которая используется как маркер для облегчения поиска вывода в сообщении об ошибке. Подзапрос SELECT (ELT(6263=6263,1)) возвращает число 1, если условие истинно (а оно всегда истинно, так как 6263=6263).

Когда MySQL пытается вычислить XPath-выражение, содержащее недопустимые символы (тильду), он генерирует ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и оказывается результат подзапроса. Атакующий может заменить ELT(6263=6263,1) на любой другой подзапрос, например, (SELECT version()) или (SELECT password FROM users LIMIT 1), и получить эти данные в тексте ошибки.

Почему это работает

Функция EXTRACTVALUE при неверном XPath-выражении возвращает ошибку, которая передаётся клиенту. Если приложение не подавляет ошибки СУБД и выводит их на страницу (или в лог, доступный атакующему), злоумышленник может читать содержимое базы данных посимвольно или целыми строками. Такой метод называется error-based SQL injection via XPath.

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

Реальный пример эксплуатации

Предположим, на сайте есть страница product.php?id=1, и параметр id подставляется в запрос:

SELECT * FROM products WHERE id = '$id'

Злоумышленник может отправить:

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

Если приложение выведет ошибку MySQL, в ней будет содержаться имя текущей базы данных. Далее можно извлекать имена таблиц, колонок и сами данные.

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

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

  • Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string (для MySQL).
  • Отключение вывода ошибок СУБД на страницы сайта. Ошибки должны логироваться, но не показываться пользователю.
  • Использование ORM или фреймворков, которые автоматически параметризуют запросы.
  • Регулярный аудит кода и сканирование уязвимостей.
  • Ограничение прав пользователя БД: приложение должно работать с минимально необходимыми привилегиями.

Также рекомендуется обновлять MySQL до актуальной версии: в новых релизах некоторые функции могут быть удалены или изменены, что усложняет эксплуатацию. Например, в MySQL 8.0 функция EXTRACTVALUE помечена как устаревшая, но всё ещё доступна.

Заключение

Error-based SQL-инъекция через EXTRACTVALUE — это мощный приём, позволяющий извлекать данные из базы через сообщения об ошибках XPath. Понимание механизма помогает разработчикам и пентестерам выявлять и устранять подобные уязвимости. Главное правило безопасности: никогда не доверяйте пользовательскому вводу и всегда используйте параметризацию запросов.

Источники