Что такое SQL-инъекция через EXTRACTVALUE?

SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в запрос, чтобы получить доступ к базе данных. Один из методов — использование функции EXTRACTVALUE в MySQL для извлечения данных через сообщения об ошибках.

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

Как работает EXTRACTVALUE в MySQL?

Синтаксис функции:

EXTRACTVALUE(XML_fragment, XPath_expression)

Функция возвращает текст из XML, соответствующий XPath. Если XPath содержит недопустимые символы, MySQL генерирует ошибку с указанием проблемного фрагмента. Именно это свойство используется в error-based SQL-инъекциях.

Пример запроса из вопроса

Рассмотрим запрос:

" ) OR EXTRACTVALUE(8643,CONCAT(0x7e,((SELECT (ELT(8643=8643,1)))),0x7e))-- -

Здесь:

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

При выполнении MySQL попытается интерпретировать строку ~1~ как XPath. Поскольку это невалидный XPath, возникнет ошибка вида: XPATH syntax error: '~1~'. В сообщении об ошибке отобразится результат подзапроса — в данном случае «1».

Зачем это нужно злоумышленнику?

Цель — извлечь данные из базы. Меняя подзапрос, можно получить имена таблиц, колонок, логины, пароли и другую конфиденциальную информацию. Например, вместо ELT(8643=8643,1) можно подставить (SELECT user FROM data LIMIT 1), и в ошибке отобразится имя пользователя.

Этот метод называется error-based SQL injection через XPATH. Он эффективен, когда приложение выводит сообщения об ошибках базы данных на страницу.

Другие функции для error-based инъекций

Помимо EXTRACTVALUE, в MySQL существуют аналогичные уязвимые функции:

  • UPDATEXML — также генерирует ошибку при невалидном XPath.
  • GTID_SUBSET — может вызывать ошибки с данными.
  • EXP — переполнение при больших числах.
  • RAND — в связке с GROUP BY.

Все они позволяют выводить данные через сообщения об ошибках, если приложение их отображает.

Как защититься от SQL-инъекций через EXTRACTVALUE?

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

Дополнительные меры:

  • Отключить вывод ошибок базы данных на страницу (в production).
  • Использовать ORM или библиотеки, автоматически экранирующие входные данные.
  • Проводить регулярные сканирования уязвимостей (например, с помощью SQLMap).
  • Ограничить права пользователя базы данных: не давать доступ к information_schema без необходимости.
  • Обновлять MySQL до последних версий — в новых релизах некоторые функции могут быть удалены или изменены.

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

Предположим, есть уязвимый параметр id в URL: http://example.com/product?id=1. Злоумышленник может подставить:

1" ) OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))-- -

В ответе сервера появится ошибка с версией MySQL. Затем можно извлекать имена таблиц, колонок и данные.

Заключение

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

Источники