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

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

Рассматриваемый запрос: ' OR EXTRACTVALUE(5376,CONCAT(0x7e,((SELECT (ELT(5376=5376,1)))),0x7e))-- - — типичный пример такой атаки. Давайте разберём его по частям.

Синтаксис и назначение функции EXTRACTVALUE

Функция EXTRACTVALUE(XML_fragment, XPath_expression) извлекает значение из XML-строки по заданному XPath-выражению. Она возвращает текст первого узла, соответствующего XPath. Если XML некорректен или XPath не находит узлов, MySQL генерирует ошибку.

Ошибка может содержать часть переданного XPath-выражения — это и используется для извлечения данных. Например, если в XPath попадает результат подзапроса, он отобразится в тексте ошибки.

Разбор вредоносного запроса

  1. ' OR ... -- - — закрывает предыдущую строку и добавляет условие OR, чтобы запрос выполнился, а комментарий -- - игнорирует остаток оригинального запроса.
  2. EXTRACTVALUE(5376, CONCAT(0x7e, ((SELECT (ELT(5376=5376,1)))), 0x7e)) — вызов функции с двумя аргументами. Первый аргумент — число 5376 (может быть любым, часто это идентификатор), второй — конкатенация тильды (0x7e — символ ~), результата подзапроса и ещё одной тильды.
  3. ELT(5376=5376,1) — функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь условие 5376=5376 истинно (1), поэтому ELT(1, 1) вернёт '1'. В реальной атаке вместо 1 мог бы быть подзапрос, извлекающий данные (например, имя пользователя).
  4. Внешние тильды нужны, чтобы отделить полезную нагрузку в сообщении об ошибке.

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

Механизм error-based атаки

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

В приведённом запросе используется EXTRACTVALUE, потому что она возвращает часть XPath в тексте ошибки. Конкатенация с 0x7e (тильда) помогает ограничить выводимые данные и облегчить их извлечение.

Важно: подобные атаки возможны только при наличии уязвимости в приложении — например, когда пользовательский ввод попадает в SQL-запрос без должной обработки.

Примеры других инъекций

Часто для error-based атак используют UNION SELECT. Например, запрос ' UNION ALL SELECT NULL,concat(0x28,username,0x3a,password,0x29) FROM users # пытается объединить результаты оригинального запроса с данными из таблицы users. Однако при несовпадении количества столбцов возникает ошибка «The used SELECT statements have a different number of columns». Это также может быть использовано для определения числа столбцов.

В отличие от UNION-инъекций, EXTRACTVALUE не требует знания количества столбцов и работает даже тогда, когда результаты запроса не отображаются на странице.

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

Основные меры защиты:

  • Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ.
  • Экранирование специальных символов при невозможности использовать подготовленные выражения.
  • Валидация и фильтрация входных данных — проверка типов, длины, допустимых символов.
  • Ограничение прав пользователя БД — не давать приложению прав на выполнение опасных функций.
  • Отключение вывода ошибок СУБД в продакшене — это усложняет эксплуатацию error-based инъекций.
  • Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.

Регулярное обновление СУБД и фреймворков также снижает риск, так как многие уязвимости закрываются в новых версиях.

Заключение

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

Источники