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

Строка %")))) AND EXTRACTVALUE(2214,CONCAT(0x7e,((SELECT (ELT(2214=2214,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Функция EXTRACTVALUE() используется для работы с XML-документами, но её особенность — генерировать ошибку с фрагментом переданного XPath-выражения, что позволяет злоумышленнику получить содержимое базы данных в тексте ошибки.

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

Функция EXTRACTVALUE(XML_document, XPath_expression) возвращает текст из XML-документа, соответствующий XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку вида:

ERROR 1105 (HY000): XPATH syntax error: '...'

В сообщении об ошибке отображается часть переданного выражения. Это и есть основа для error-based инъекции: злоумышленник может подставить в XPath-выражение результат подзапроса, и если он содержит недопустимые символы (например, тильду ~), MySQL вернёт ошибку с внедрёнными данными.

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

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

  • %")))) — часть, которая «ломает» исходный SQL-запрос, закрывая кавычки и скобки, чтобы вставить свой код.
  • AND EXTRACTVALUE(2214, CONCAT(0x7e, ((SELECT (ELT(2214=2214,1)))), 0x7e)) — вызов уязвимой функции. Здесь 2214 — произвольное число (может быть любым), 0x7e — шестнадцатеричное представление символа ~ (тильда).
  • ELT(2214=2214,1) — функция ELT() возвращает N-й элемент из списка. В данном случае условие 2214=2214 всегда истинно, поэтому возвращается 1. Это простейший пример; на практике вместо 1 подставляется подзапрос, извлекающий данные (например, имя пользователя, хеш пароля).
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса.

Таким образом, при выполнении этого кода MySQL попытается вычислить XPath-выражение, содержащее символ ~, что вызовет ошибку с текстом, включающим результат подзапроса. Например, если вместо 1 подставить (SELECT user()), ошибка покажет текущего пользователя БД.

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

Error-based инъекции — мощный инструмент, когда приложение не выводит данные напрямую, но отображает ошибки СУБД. С помощью EXTRACTVALUE можно посимвольно извлекать любые данные: имена таблиц, столбцов, логины, пароли. Это один из этапов атаки на веб-приложение с недостаточной фильтрацией входных данных.

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

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

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

В ответе сервера появится ошибка: XPATH syntax error: '~mydb~', где mydb — имя текущей базы данных. Аналогично можно извлечь версию MySQL, имена таблиц и другие сведения.

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

Основная причина уязвимости — динамическое построение SQL-запросов с прямым включением пользовательского ввода. Меры защиты:

  1. Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ.
  2. Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string() (для MySQL).
  3. Валидация и фильтрация входных данных — например, приведение id к целому числу.
  4. Отключение вывода ошибок СУБД на продакшене. Ошибки должны логироваться, а не показываться пользователю.
  5. Использование ORM (например, Doctrine, Hibernate), которые автоматически параметризуют запросы.
  6. Регулярное обновление СУБД — в новых версиях MySQL некоторые опасные функции могут быть удалены или ограничены.

Заключение

Запрос с EXTRACTVALUE — это не просто случайный набор символов, а тщательно сконструированная атака на базу данных MySQL. Понимание её механизма помогает разработчикам и администраторам лучше защищать свои системы. Никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы — это золотое правило веб-безопасности.

Источники