Что это за строка?

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

Разбор по частям

Давайте разберём каждый элемент запроса:

  • ' — одиночная кавычка, которая закрывает строковый литерал в оригинальном SQL-запросе, встраивая наш код.
  • OR — логический оператор, позволяющий обойти условие и выполнить нашу инъекцию.
  • EXTRACTVALUE(4293, CONCAT(...)) — функция MySQL для извлечения значения из XML. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath некорректен, функция возвращает ошибку с текстом, содержащим переданное выражение. Это и используется для вывода данных.
  • CONCAT(0x7e, ((SELECT (ELT(4293=4293,1)))), 0x7e) — объединяет символы тильды (0x7e) с результатом подзапроса. 0x7e — это шестнадцатеричное представление символа ~, который используется как маркер для облегчения поиска данных в сообщении об ошибке.
  • SELECT (ELT(4293=4293,1)) — подзапрос, который возвращает 1, если условие 4293=4293 истинно (а оно всегда истинно). Функция ELT возвращает N-й элемент из списка; здесь она возвращает 1. В реальной атаке вместо этого подзапроса может быть запрос к базе данных, например, SELECT password FROM users LIMIT 1.
  • -- - — комментарий, который обрезает оставшуюся часть оригинального запроса, чтобы избежать синтаксических ошибок.

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

Когда веб-приложение подставляет пользовательский ввод в SQL-запрос без должной обработки, злоумышленник может внедрить свой код. В данном случае цель — заставить базу данных выполнить подзапрос и вернуть его результат в тексте ошибки. Функция EXTRACTVALUE пытается интерпретировать переданную строку как XPath. Поскольку выражение CONCAT(0x7e, ..., 0x7e) не является валидным XPath, MySQL генерирует ошибку вида:

XPATH syntax error: '~1~'

В этом сообщении как раз и отображается результат подзапроса, обёрнутый в тильды. Таким образом, атакующий может извлекать произвольные данные из базы, если подзапрос возвращает нужную информацию.

Зачем нужна такая инъекция?

Error-based SQL-инъекции используются, когда приложение не выводит результаты запроса напрямую, но отображает сообщения об ошибках базы данных. Это позволяет злоумышленнику получать данные посимвольно или целыми строками, в зависимости от конструкции. В приведённом примере подзапрос возвращает константу 1, что демонстрирует работоспособность метода. В реальной атаке вместо ELT(4293=4293,1) могут быть подставлены запросы к системным таблицам, например, SELECT table_name FROM information_schema.tables LIMIT 1.

Опасность и последствия

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

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

Основные меры защиты от SQL-инъекций:

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

Пример безопасного кода

Вместо конкатенации строк используйте параметризованные запросы. Например, на PHP с PDO:

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

Такой подход гарантирует, что ввод пользователя не будет интерпретирован как SQL-код.

Заключение

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

Источники