Что такое Extractvalue в SQL

Extractvalue — это встроенная функция в некоторых системах управления базами данных (СУБД), например в Oracle и MySQL (до версии 8.0). Она предназначена для извлечения значения из XML-документа с помощью выражения XPath. Функция возвращает текстовое содержимое узла, соответствующего заданному пути. Если узел является элементом, он должен содержать единственный текстовый дочерний узел — именно его значение и возвращается.

В Oracle функция Extractvalue принимает два аргумента: экземпляр XMLType и выражение XPath. Результат должен быть единственным узлом — текстовым, атрибутом или элементом. Если выражение XPath возвращает несколько узлов или узел не соответствует требованиям, генерируется ошибка.

Синтаксис и примеры использования

Общий синтаксис функции:

EXTRACTVALUE(xml_документ, 'XPath_выражение')

Например, имеется XML:

<book><title>SQL для профи</title><author>Иванов</author></book>

Запрос:

SELECT EXTRACTVALUE(xml_column, '/book/title') FROM books;

вернёт строку «SQL для профи».

В MySQL функция ExtractValue() работала аналогично, но была удалена в версии 8.0. Вместо неё рекомендуется использовать функции JSON или XML-функции, такие как ExtractValue() заменена на JSON_EXTRACT() для JSON-данных.

Extractvalue и SQL-инъекции

Одна из причин, по которой Extractvalue часто упоминается в контексте безопасности — это возможность использования функции для проведения SQL-инъекций. Злоумышленники могут внедрить вызов Extractvalue в уязвимый параметр запроса, чтобы извлечь данные из базы. Например, конструкция вида:

' AND EXTRACTVALUE(1395,CONCAT(0x7e,((SELECT (ELT(1395=1395,1)))),0x7e))-- -

пытается вызвать ошибку, содержащую результат подзапроса. В данном случае ELT(1395=1395,1) возвращает 1 (так как условие истинно), и CONCAT формирует строку с тильдами. Extractvalue получает неверный XPath и генерирует ошибку, в тексте которой может отобразиться переданное значение. Это классический пример error-based SQL-инъекции.

Подобные техники использовались для получения имён таблиц, колонок и других данных. Защита от таких атак — использование параметризованных запросов и экранирование пользовательского ввода.

Аналоги и замена

В современных СУБД функция Extractvalue либо устарела, либо отсутствует. В MySQL 8.0 и выше для работы с XML можно использовать функции ExtractValue() (удалена), а для JSON — JSON_EXTRACT(). В Oracle функция Extractvalue помечена как устаревшая (deprecated) начиная с версии 12c, рекомендуется применять XMLQuery или XMLTable.

В PostgreSQL для извлечения из XML используется xpath() или XMLTABLE.

Безопасность и лучшие практики

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

Функция Extractvalue — мощный инструмент для работы с XML, но её использование требует осторожности. Понимание принципов её работы помогает как разработчикам, так и специалистам по безопасности.

Источники