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

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

В вашем запросе: " AND EXTRACTVALUE(1388,CONCAT(0x7e,((SELECT (ELT(1388=1388,1)))),0x7e))-- - — используется именно этот приём. Давайте разберём его по частям.

Синтаксис и назначение EXTRACTVALUE

EXTRACTVALUE(XML_fragment, XPath_expression) — функция MySQL, которая извлекает значение из XML-строки по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL возвращает ошибку с текстом, содержащим переданное выражение. Это и эксплуатируется в error-based инъекциях.

Пример легитимного использования:

SELECT EXTRACTVALUE('<a><b>текст</b></a>', '/a/b');
-- Результат: текст

Если же передать заведомо неверный XPath, например содержащий символ ~, функция выдаст ошибку вида:

XPATH syntax error: '~...~'

Именно этот побочный эффект используется для вывода данных.

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

Рассмотрим внедряемый фрагмент:

" AND EXTRACTVALUE(1388,CONCAT(0x7e,((SELECT (ELT(1388=1388,1)))),0x7e))-- -
  • " — закрывает предыдущую строковую константу в уязвимом запросе.
  • AND — логический оператор для присоединения условия.
  • EXTRACTVALUE(1388, ...) — первый аргумент (1388) — произвольный XML-фрагмент, не влияющий на результат; второй — XPath-выражение, которое мы конструируем.
  • CONCAT(0x7e, ..., 0x7e) — объединяет символ ~ (0x7e) с полезной нагрузкой и ещё одним ~. Тильда нужна, чтобы XPath был синтаксически неверным и вызвал ошибку.
  • (SELECT (ELT(1388=1388,1))) — подзапрос, возвращающий результат выражения ELT(1388=1388,1). ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь условие 1388=1388 истинно (1), поэтому ELT(1,1) вернёт 1. В реальной атаке вместо этого подзапроса подставляют извлечение данных, например (SELECT version()).
  • -- - — комментарий, обрезающий остаток исходного запроса.

В результате MySQL выполнит функцию EXTRACTVALUE с XPath, содержащим тильды и значение подзапроса, что вызовет ошибку с текстом, включающим это значение. Злоумышленник увидит его в ответе сервера.

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

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

SELECT * FROM users WHERE id = '1' AND ...

Подставив полезную нагрузку, хакер может заставить базу вернуть версию СУБД, имя базы или хэши паролей. Например:

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

Ответ сервера будет содержать сообщение об ошибке: XPATH syntax error: '~5.7.23~'. Так утекает информация.

В вашем случае с ELT(1388=1388,1) это, скорее всего, тестовый запрос для проверки наличия уязвимости. Если при подстановке условия 1388=1388 (всегда истинного) ошибка возникает, а при 1388=1389 — нет, значит, инъекция возможна.

Почему это опасно?

Error-based SQL-инъекции через EXTRACTVALUE позволяют быстро извлекать данные, не прибегая к слепым методам. Злоумышленник может получить:

  • учётные данные пользователей (логины, пароли в открытом или хэшированном виде);
  • персональные данные клиентов;
  • структуру базы данных (имена таблиц и колонок);
  • полный контроль над сервером БД в некоторых конфигурациях.

По данным OWASP, SQL-инъекции остаются в топ-10 критических угроз веб-приложений уже много лет.

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

Основной метод защиты — параметризованные запросы (prepared statements). Они разделяют код и данные, поэтому внедрённый SQL не выполняется. Пример на PHP с PDO:

$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $userId]);

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

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

Важно понимать: никакая фильтрация чёрных списков не даёт 100% гарантии. Только параметризация — надёжное решение.

Заключение

Запрос " AND EXTRACTVALUE(1388,CONCAT(0x7e,((SELECT (ELT(1388=1388,1)))),0x7e))-- - — типичный пример error-based SQL-инъекции, эксплуатирующей функцию EXTRACTVALUE в MySQL. Понимание механизма таких атак помогает разработчикам и специалистам по безопасности своевременно закрывать уязвимости. Помните: лучшая защита — параметризованные запросы и минимальные привилегии для учётной записи базы данных.

Источники