Введение

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

Что такое EXTRACTVALUE?

EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа с помощью выражения XPath. Синтаксис функции:

EXTRACTVALUE(XML_фрагмент, XPath_выражение)

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

Как EXTRACTVALUE используется в SQL-инъекциях

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

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

Разберём этот запрос по частям:

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

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

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

Функция EXTRACTVALUE при неверном XPath выдаёт ошибку, которая возвращается клиенту (если приложение не подавляет ошибки). Это позволяет реализовать так называемую error-based SQL-инъекцию — один из самых удобных для злоумышленника методов, поскольку не требует слепого перебора и даёт немедленный результат.

Аналогичными возможностями обладают функции UPDATEXML и GTID_SUBSET (в некоторых версиях MySQL). Все они эксплуатируют вывод ошибок для передачи данных.

Пример реальной атаки

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

SELECT * FROM users WHERE name = '$input';

Если передать в $input строку:

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

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

Методы защиты

Чтобы предотвратить инъекции через EXTRACTVALUE и другие подобные функции, необходимо применять комплекс мер:

  1. Использование подготовленных выражений (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода, и внедрение становится невозможным.
  2. Экранирование специальных символов. Если по каким-то причинам prepared statements недоступны, следует использовать функции экранирования (например, mysqli_real_escape_string).
  3. Отключение вывода ошибок СУБД в production. Сообщения об ошибках не должны попадать в ответ клиенту. Логирование ошибок должно вестись на сервере.
  4. Ограничение прав пользователя БД. Приложение должно работать под учётной записью с минимально необходимыми привилегиями, чтобы даже при успешной инъекции ущерб был ограничен.
  5. Использование WAF (Web Application Firewall). Современные WAF умеют распознавать шаблоны атак, включая EXTRACTVALUE.
  6. Регулярное обновление СУБД. В новых версиях MySQL некоторые опасные функции могут быть удалены или изменены.

Заключение

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

Источники