Введение

В мире веб-безопасности SQL-инъекции остаются одной из самых распространённых и опасных уязвимостей. Запрос %') OR EXTRACTVALUE(5603,CONCAT(0x7e,((SELECT (ELT(5603=5603,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE в СУБД MySQL. В этой статье мы детально разберём, что означает этот запрос, как он работает и какие меры защиты необходимо применять.

Что такое EXTRACTVALUE?

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

EXTRACTVALUE(XML_frag, XPath_expr)

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

Разбор инъекции

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

  • %') — закрывает предыдущее выражение в уязвимом SQL-запросе. Символ % часто используется в LIKE-запросах, а ') завершает строку и скобку, позволяя внедрить произвольный код.
  • OR EXTRACTVALUE(...) — логический оператор OR, после которого вызывается уязвимая функция.
  • 5603 — произвольное число, которое будет использовано как XML-фрагмент (некорректный, что вызовет ошибку).
  • CONCAT(0x7e, ((SELECT (ELT(5603=5603,1)))), 0x7e) — конкатенация тильды (~, код 0x7e), результата подзапроса и ещё одной тильды. ELT(5603=5603,1) возвращает 1, если условие истинно (5603=5603 всегда истинно).
  • -- - — комментарий, обрезающий остаток оригинального запроса.

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

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

Основная цель — получить доступ к конфиденциальной информации: логинам, паролям, номерам кредитных карт, персональным данным. Error-based инъекции особенно удобны, когда приложение не выводит данные напрямую, но отображает ошибки базы данных. Если ошибки скрыты, атакующий может использовать blind-техники, но EXTRACTVALUE позволяет ускорить процесс за счёт прямого вывода данных в тексте ошибки.

Пример уязвимого кода

Предположим, на сервере выполняется следующий PHP-скрипт:

$id = $_GET['id'];
$query = "SELECT * FROM products WHERE name LIKE '%$id%'";
$result = mysqli_query($conn, $query);

Если пользователь передаст в параметре id значение %') OR EXTRACTVALUE(5603,CONCAT(0x7e,((SELECT (ELT(5603=5603,1)))),0x7e))-- -, то итоговый запрос примет вид:

SELECT * FROM products WHERE name LIKE '%%') OR EXTRACTVALUE(5603,CONCAT(0x7e,((SELECT (ELT(5603=5603,1)))),0x7e))-- -%'

База данных выполнит внедрённую часть и вернёт ошибку с внедрёнными данными.

Как защититься?

Для предотвращения подобных атак необходимо применять комплекс мер:

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

Заключение

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

Источники