Spec-Zone .ru
спецификации, руководства, описания, API
|
Таблица 12.15. XML Функции
Имя | Описание |
---|---|
ExtractValue()
|
Извлекает значение из строки XML, используя нотацию XPath |
UpdateXML()
|
Возвратите замененный фрагмент XML |
Этот раздел обсуждает XML и связанную функциональность в MySQL.
Возможно получить отформатированный XML вывод из MySQL в mysql и mysqldump клиентах, вызывая их с --xml
опция. См. Раздел
4.5.1, "mysql — MySQL Command-Line Tool", и Раздел
4.5.4, "mysqldump — Программа Резервного копирования базы
данных".
Две функции, обеспечивающие основной XPath 1.0 (Язык Пути XML, версия 1.0) возможности, доступны. Некоторая
основная информация о синтаксисе XPath и использовании обеспечивается позже в этом разделе; однако, всестороннее
обсуждение этих тем выходит за рамки этого Руководства, и следует отослать к
Эти функции остаются разрабатываемыми. Мы продолжаем улучшать эти и другие аспекты XML и
функциональности XPath в MySQL 5.6 и вперед. Можно обсудить их, задать вопросы о них, и получить справку от
других пользователей с ними на
Выражения XPath, используемые с этими функциями, поддерживают пользовательские переменные и локальные сохраненные переменные программы. Пользовательские переменные слабо проверяются; переменные, локальные для сохраненных программ, строго проверяются (см. также Ошибку #26518):
Пользовательские переменные (слабая проверка). Переменные используя синтаксис
$@
(то есть,
пользовательские переменные), не проверяются. Никакие предупреждения или ошибки не выпускаются сервером,
если переменная имеет неправильный тип или не была ранее присвоена значение. Это также означает, что
пользователь полностью ответственен за любые типографские ошибки, так как никакие предупреждения не
будут даны если (например) variable_name
$@myvairable
используется где $@myvariable
был предназначен.
Пример:
mysql>SET @xml = '<a><b>X</b><b>Y</b></a>';
Query OK, 0 rows affected (0.00 sec)mysql>SET @i =1, @j = 2;
Query OK, 0 rows affected (0.00 sec)mysql>SELECT @i, ExtractValue(@xml, '//b[$@i]');
+------+--------------------------------+| @i | ExtractValue(@xml, '//b[$@i]') |+------+--------------------------------+| 1 | X |+------+--------------------------------+1 row in set (0.00 sec)mysql>SELECT @j, ExtractValue(@xml, '//b[$@j]');
+------+--------------------------------+| @j | ExtractValue(@xml, '//b[$@j]') |+------+--------------------------------+| 2 | Y |+------+--------------------------------+1 row in set (0.00 sec)mysql>SELECT @k, ExtractValue(@xml, '//b[$@k]');
+------+--------------------------------+| @k | ExtractValue(@xml, '//b[$@k]') |+------+--------------------------------+| NULL | |+------+--------------------------------+1 row in set (0.00 sec)
Переменные в сохраненных программах (проверка strong). Переменные используя
синтаксис $
может
быть объявлен и использоваться с этими функциями, когда их вызывают в сохраненных программах. Такие
переменные локальны для сохраненной программы, в которой они определяются, и строго проверяются на тип и
значение. variable_name
Пример:
mysql>DELIMITER |
mysql>CREATE PROCEDURE myproc ()
->BEGIN
->DECLARE i INT DEFAULT 1;
->DECLARE xml VARCHAR(25) DEFAULT '<a>X</a><a>Y</a><a>Z</a>';
-> ->WHILE i < 4 DO
->SELECT xml, i, ExtractValue(xml, '//a[$i]');
->SET i = i+1;
->END WHILE;
->END |
Query OK, 0 rows affected (0.01 sec)mysql>DELIMITER ;
mysql>CALL myproc;
+--------------------------+---+------------------------------+| xml | i | ExtractValue(xml, '//a[$i]') |+--------------------------+---+------------------------------+| <a>X</a><a>Y</a><a>Z</a> | 1 | X |+--------------------------+---+------------------------------+1 row in set (0.00 sec)+--------------------------+---+------------------------------+| xml | i | ExtractValue(xml, '//a[$i]') |+--------------------------+---+------------------------------+| <a>X</a><a>Y</a><a>Z</a> | 2 | Y |+--------------------------+---+------------------------------+1 row in set (0.01 sec)+--------------------------+---+------------------------------+| xml | i | ExtractValue(xml, '//a[$i]') |+--------------------------+---+------------------------------+| <a>X</a><a>Y</a><a>Z</a> | 3 | Z |+--------------------------+---+------------------------------+1 row in set (0.01 sec)
Параметры. Переменные, используемые в выражениях XPath в сохраненных подпрограммах, в которых передают как параметры, также подвергаются проверке strong.
Выражения, содержащие пользовательские переменные или переменные, локальные для сохраненных программ, должны иначе (за исключением нотации), соответствуют правилам для выражений XPath, содержащих переменные как дано в XPath 1.0 спецификации.
В настоящий момент пользовательская переменная, используемая, чтобы сохранить выражение XPath, обрабатывается как пустая строка. Из-за этого не возможно сохранить выражение XPath как пользовательскую переменную. (Ошибка #32911)
ExtractValue(
xml_frag
, xpath_expr
)
ExtractValue()
берет два строковых параметра, фрагмент разметки XML
xml_frag
и выражение XPath xpath_expr
(также известный как локатор); это возвращает текст (CDATA
) из первого текстового узла, который является дочерним
элементом элементов или элементов, соответствующих выражением XPath. В MySQL 5.6.6 и ранее,
выражение XPath могло содержать самое большее 127 символов. Это ограничение было снято в MySQL
5.6.7. (Ошибка #13007062, Bug#62429)
Используя эту функцию эквивалент выполнения соответствия, используя xpath_expr
после добавления /text()
. Другими словами, ExtractValue('<a><b>Sakila</b></a>', '/a/b')
и ExtractValue('<a><b>Sakila</b></a>',
'/a/b/text()')
приведите к тому же самому результату.
Если многократные соответствия находятся, контент первого дочернего текстового узла каждого элемента соответствия возвращается (в соответствующем порядке) как единственная, разграниченная пространством строка.
Если никакой текстовый узел соответствия не находится для выражения (включая неявное /text()
) — по любой причине, пока xpath_expr
допустимо, и xml_frag
состоит из элементов, которые
должным образом вкладываются и закрываются — возвращается, пустая строка. Никакое различие не
делается между соответствием на пустом элементе и никаким соответствием вообще. Это проектом.
Если Вы должны определить, не был ли никакой элемент соответствия найден в xml_frag
или такой элемент был найден, но не содержал
дочерних текстовых узлов, следует протестировать результат выражения, которое использует XPath count()
функция. Например, оба из этих операторов возвращают пустую
строку, как показано сюда:
mysql>SELECT ExtractValue('<a><b/></a>', '/a/b');
+-------------------------------------+| ExtractValue('<a><b/></a>', '/a/b') |+-------------------------------------+| |+-------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue('<a><c/></a>', '/a/b');
+-------------------------------------+| ExtractValue('<a><c/></a>', '/a/b') |+-------------------------------------+| |+-------------------------------------+1 row in set (0.00 sec)
Однако, можно определить, был ли фактически соответствующий элемент, используя следующее:
mysql>SELECT ExtractValue('<a><b/></a>', 'count(/a/b)');
+-------------------------------------+| ExtractValue('<a><b/></a>', 'count(/a/b)') |+-------------------------------------+| 1 |+-------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue('<a><c/></a>', 'count(/a/b)');
+-------------------------------------+| ExtractValue('<a><c/></a>', 'count(/a/b)') |+-------------------------------------+| 0 |+-------------------------------------+1 row in set (0.01 sec)
ExtractValue()
возвраты только CDATA
, и не возвращает тегов, которые могли бы
содержаться в пределах соответствующего тега, ни любого их контента (см. результат, возвращенный
как val1
в следующем примере).
mysql>SELECT
->ExtractValue('<a>ccc<b>ddd</b></a>', '/a') AS val1,
->ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b') AS val2,
->ExtractValue('<a>ccc<b>ddd</b></a>', '//b') AS val3,
->ExtractValue('<a>ccc<b>ddd</b></a>', '/b') AS val4,
->ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;
+------+------+------+------+---------+| val1 | val2 | val3 | val4 | val5 |+------+------+------+------+---------+| ccc | ddd | ddd | | ddd eee |+------+------+------+------+---------+
Эта функция использует текущее сопоставление SQL для того, чтобы сделать сравнения с contains()
, выполнение той же самой агрегации сопоставления как другие
строковые функции (такой как CONCAT()
), в принятии во внимание сопоставления coercibility их
параметров; см. Раздел 10.1.7.5, "Сопоставление
Выражений", для объяснения правил, управляющих этим поведением.
(Ранее, двоичный файл — то есть, чувствительный к регистру — сравнение всегда использовалось.)
NULL
возвращается если xml_frag
содержит элементы, которые должным образом не
вкладываются или закрываются, и предупреждение сгенерировано, как показано в этом примере:
mysql>SELECT ExtractValue('<a>c</a><b', '//a');
+-----------------------------------+| ExtractValue('<a>c</a><b', '//a') |+-----------------------------------+| NULL |+-----------------------------------+1 row in set, 1 warning (0.00 sec)mysql>SHOW WARNINGS;
+---------+------+-------------------------------------------------------------------------------------------+| Level | Code | Message |+---------+------+-------------------------------------------------------------------------------------------+| Warning | 1523 | Incorrect XML value: 'parse error at line 1 pos 11: END-OF-INPUT unexpected ('>' wanted)' |+---------+------+-------------------------------------------------------------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue('<a>c</a><b/>', '//a');
+-------------------------------------+| ExtractValue('<a>c</a><b/>', '//a') |+-------------------------------------+| c |+-------------------------------------+1 row in set (0.00 sec)
UpdateXML(
xml_target
, xpath_expr
, new_xml
)
Эта функция заменяет единственную часть данного фрагмента разметки XML xml_target
с новым фрагментом XML new_xml
,
и затем возвращает измененный XML. Часть xml_target
это
заменяется, соответствует выражение XPath xpath_expr
предоставленный пользователем. В MySQL 5.6.6 и ранее, выражение XPath могло содержать самое большее
127 символов. Это ограничение снимается в MySQL 5.6.7. (Ошибка #13007062, Ошибка #62429)
Если никакое соответствие выражения xpath_expr
находится,
или если многократные соответствия находятся, функция возвращает оригинал xml_target
Фрагмент XML. Всеми тремя параметрами
должны быть строки.
mysql>SELECT
->UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
->UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
->UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
->UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4,
->UpdateXML('<a><d></d><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val5
->\G
*************************** 1. row ***************************val1: <e>fff</e>val2: <a><b>ccc</b><d></d></a>val3: <a><e>fff</e><d></d></a>val4: <a><b>ccc</b><e>fff</e></a>val5: <a><d></d><b>ccc</b><d></d></a>
Обсуждение подробно синтаксиса XPath и использования выходит за рамки этого Руководства.
Пожалуйста, см.
Описания и примеры некоторых основных выражений XPath следуют:
/
tag
Соответствия <
если и только если tag
/><
корневой элемент. tag
/>
Пример: /a
имеет соответствие в <a><b/></a>
потому что это соответствует наиболее удаленный (корневой) тег. Это не соответствует внутреннее a
элемент в <b><a/></b>
потому что в этом экземпляре это - дочерний элемент другого элемента.
/
tag1
/tag2
Соответствия <
если и только если это - дочерний элемент tag2
/><
, и tag1
/>
<
корневой элемент. tag1
/>
Пример: /a/b
соответствия b
элемент во фрагменте XML <a><b/></a>
потому что это -
дочерний элемент корневого элемента a
. У этого нет
соответствия в <b><a/></b>
потому что в этом случае,
b
корневой элемент (и следовательно дочерний элемент
никакого другого элемента). И при этом у выражения XPath нет соответствия в
<a><c><b/></c></a>
; здесь, b
потомок a
,
но не фактически дочерний элемент a
.
Эта конструкция является растяжимой к трем или больше элементам. Например, выражение XPath /a/b/c
соответствия c
элемент
во фрагменте <a><b><c/></b></a>
.
//
tag
Соответствия любой экземпляр <
. tag
>
Пример: //a
соответствия a
элемент в любом следующем:
<a><b><c/></b></a>
; <c><a><b/></a></b>
;
<c><b><a/></b></c>
.
//
может быть объединен с /
. Например,
//a/b
соответствия b
элемент
в любом из фрагментов <a><b/></a>
или <a><b><c/></b></a>
//
эквивалент
tag
/descendant-or-self::*/
. Распространенная ошибка состоит в том,
чтобы перепутать это с tag
/descendant-or-self::
,
хотя последнее выражение может фактически привести к совсем другим результатам, как может быть
замечен здесь: tag
mysql>SET @xml = '<a><b><c>w</c><b>x</b><d>y</d>z</b></a>';
Query OK, 0 rows affected (0.00 sec)mysql>SELECT @xml;
+-----------------------------------------+| @xml |+-----------------------------------------+| <a><b><c>w</c><b>x</b><d>y</d>z</b></a> |+-----------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue(@xml, '//b[1]');
+------------------------------+| ExtractValue(@xml, '//b[1]') |+------------------------------+| x z |+------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue(@xml, '//b[2]');
+------------------------------+| ExtractValue(@xml, '//b[2]') |+------------------------------+| |+------------------------------+1 row in set (0.01 sec)mysql>SELECT ExtractValue(@xml, '/descendant-or-self::*/b[1]');
+---------------------------------------------------+| ExtractValue(@xml, '/descendant-or-self::*/b[1]') |+---------------------------------------------------+| x z |+---------------------------------------------------+1 row in set (0.06 sec)mysql>SELECT ExtractValue(@xml, '/descendant-or-self::*/b[2]');
+---------------------------------------------------+| ExtractValue(@xml, '/descendant-or-self::*/b[2]') |+---------------------------------------------------+| |+---------------------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue(@xml, '/descendant-or-self::b[1]');
+-------------------------------------------------+| ExtractValue(@xml, '/descendant-or-self::b[1]') |+-------------------------------------------------+| z |+-------------------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue(@xml, '/descendant-or-self::b[2]');
+-------------------------------------------------+| ExtractValue(@xml, '/descendant-or-self::b[2]') |+-------------------------------------------------+| x |+-------------------------------------------------+1 row in set (0.00 sec)
*
оператор действует как "подстановочный знак", который соответствует любой элемент.
Например, выражение /*/b
соответствия b
элемент в любом из фрагментов XML
<a><b/></a>
или <c><b/></c>
.
Однако, выражение не производит соответствие во фрагменте <b><a/></b>
потому что b
должен быть дочерний элемент некоторого другого
элемента. Подстановочный знак может использоваться в любой позиции: выражение /*/b/*
будет соответствовать любому дочернему элементу a b
элемент,
который является самостоятельно не корневым элементом.
Можно соответствовать любой из нескольких локаторов, используя |
(UNION
)
оператор. Например, выражение //b|//c
соответствия все b
и c
элементы в
цели XML.
Также возможно соответствовать элемент, основанный на значении один или больше его
атрибутов. Это сделанное использование синтаксиса
.
Например, выражение tag
[@attribute
="value
"]//b[@id="idB"]
соответствует второе b
элемент во фрагменте <a><b
id="idA"/><c/><b id="idB"/></a>
. Соответствовать
против любого наличия элемента
, используйте выражение XPath attribute
="value
"
//*[
.
attribute
="value
"]
Чтобы фильтровать многократные значения атрибута, просто используйте многократные пункты сравнения
атрибута по очереди. Например, выражение //b[@c="x"][@d="y"]
соответствует элемент <b c="x" d="y"/>
появление где угодно в данном фрагменте XML.
Чтобы найти элементы, для которых тот же самый атрибут соответствует любое из нескольких значений,
можно использовать многократные локаторы, к которым присоединяются |
оператор. Например, чтобы соответствовать все b
элементы,
чей c
атрибуты имеют или значений 23 или 17, используют
выражение //b[@c="23"]|//b[@c="17"]
. Можно также
использовать логическое or
оператор с этой целью: //b[@c="23" or @c="17"]
.
Различие между or
и |
это
or
условия соединений, в то время как |
наборы результатов соединений.
Ограничения XPath. Синтаксис XPath, поддерживаемый этими функциями, в настоящий момент подвергается следующим ограничениям:
Сравнение от набора узлов к набору узлов (такой как '/a/b[@c=@d]'
)
не поддерживается.
Все стандартные операторы сравнения XPath поддерживаются. (Ошибка #22823)
Относительные выражения локатора разрешаются в контексте корневого узла. Например, рассмотрите следующий запрос и результат:
mysql>SELECT ExtractValue(
->'<a><b c="1">X</b><b c="2">Y</b></a>',
->'a/b'
->) AS result;
+--------+| result |+--------+| X Y |+--------+1 row in set (0.03 sec)
В этом случае, локатор a/b
решения к /a/b
.
Относительные локаторы также поддерживаются в пределах предикатов. В следующем примере, d[../@c="1"]
разрешается как /a/b[@c="1"]/d
:
mysql>SELECT ExtractValue(
->'<a>
-><b c="1"><d>X</d></b>
-><b c="2"><d>X</d></b>
-></a>',
->'a/b/d[../@c="1"]')
->AS result;
+--------+| result |+--------+| X |+--------+1 row in set (0.00 sec)
Локаторы, снабженные префиксом выражения, которые оценивают как скалярные значения — включая переменные ссылки, литералы, числа, и вызовы скалярной функции — не разрешаются, и их результаты использования по ошибке.
::
оператор не поддерживается в комбинации с типами
узла, такими как следующее:
axis
::comment()
axis
::text()
axis
::processing-instructions()
axis
::node()
Однако, назовите тесты (такой как
и axis
::name
) поддерживаются, как показано в этих
примерах: axis
::*
mysql>SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b');
+-------------------------------------------------------+| ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b') |+-------------------------------------------------------+| x |+-------------------------------------------------------+1 row in set (0.02 sec)mysql>SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*');
+-------------------------------------------------------+| ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*') |+-------------------------------------------------------+| x y |+-------------------------------------------------------+1 row in set (0.01 sec)
"Вверх и вниз" навигация не поддерживается в случаях, куда путь вел бы "выше" корневого элемента. Таким образом, невозможно использовать выражения, которые соответствуют на потомках предков данного элемента, где один или больше предков текущего элемента также предок корневого элемента (см. Ошибку #16321).
Следующие функции XPath не поддерживаются, или знали проблемы как обозначено:
id()
lang()
local-name()
name()
namespace-uri()
normalize-space()
starts-with()
string()
substring-after()
substring-before()
translate()
Следующие оси не поддерживаются:
following-sibling
following
preceding-sibling
preceding
Выражения XPath, которые передают как параметры ExtractValue()
и UpdateXML()
может содержать символ двоеточия (":
") в селекторах элемента, который включает их
использованию с разметкой, использующей нотацию пространств имен XML. Например:
mysql>SET @xml = '<a>111<b:c>222<d>333</d><e:f>444</e:f></b:c></a>';
Query OK, 0 rows affected (0.00 sec)mysql>SELECT ExtractValue(@xml, '//e:f');
+-----------------------------+| ExtractValue(@xml, '//e:f') |+-----------------------------+| 444 |+-----------------------------+1 row in set (0.00 sec)mysql>SELECT UpdateXML(@xml, '//b:c', '<g:h>555</g:h>');
+--------------------------------------------+| UpdateXML(@xml, '//b:c', '<g:h>555</g:h>') |+--------------------------------------------+| <a>111<g:h>555</g:h></a> |+--------------------------------------------+1 row in set (0.00 sec)
Это подобно в некотором отношении тому, что разрешается namespace-uri()
и local-name()
функции.
Обработка ошибок. Для обоих ExtractValue()
и UpdateXML()
, используемый локатор XPath должен быть допустимым, и XML, который
будет искаться, должен состоять из элементов, которые должным образом вкладываются и закрываются. Если локатор
недопустим, ошибка сгенерирована:
mysql> SELECT ExtractValue('<a>c</a><b/>',
'/&a');
ERROR 1105 (HY000): XPATH syntax error: '&a'
Если xml_frag
не состоит из элементов, которые должным образом
вкладываются и закрываются, NULL
возвращается и предупреждение сгенерировано, как
показано в этом примере:
mysql>SELECT ExtractValue('<a>c</a><b', '//a');
+-----------------------------------+| ExtractValue('<a>c</a><b', '//a') |+-----------------------------------+| NULL |+-----------------------------------+1 row in set, 1 warning (0.00 sec)mysql>SHOW WARNINGS;
+---------+------+-------------------------------------------------------------------------------------------+| Level | Code | Message |+---------+------+-------------------------------------------------------------------------------------------+| Warning | 1523 | Incorrect XML value: 'parse error at line 1 pos 11: END-OF-INPUT unexpected ('>' wanted)' |+---------+------+-------------------------------------------------------------------------------------------+1 row in set (0.00 sec)mysql>SELECT ExtractValue('<a>c</a><b/>', '//a');
+-------------------------------------+| ExtractValue('<a>c</a><b/>', '//a') |+-------------------------------------+| c |+-------------------------------------+1 row in set (0.00 sec)
Заменяющий XML, используемый в качестве третьего параметра UpdateXML()
не проверяется, чтобы
определить, состоит ли это исключительно из элементов, которые должным образом вкладываются и закрываются.
Инжекция XPath. инжекция кода происходит, когда вредоносный код вводится в систему, чтобы получить несанкционированный доступ к полномочиям и данным. Это основано на использовании предположений, сделанных разработчиками о типе и контенте ввода данных от пользователей. XPath не является никаким исключением в этом отношении.
Общий сценарий, в котором это может произойти, имеет место приложения, которое обрабатывает авторизацию, соответствуя комбинацию имени для входа в систему и пароля с найденными в XML-файле, используя выражение XPath как этот:
//user[login/text()='neapolitan' and password/text()='1c3cr34m']/attribute::id
Это - XPath, эквивалентный из SQL-оператора как этот:
SELECT id FROM users WHERE login='neapolitan' AND password='1c3cr34m';
Приложение PHP, использующее XPath, могло бы обработать процесс входа в систему как это:
<?php $file = "users.xml"; $login = $POST["login"]; $password = $POST["password"]; $xpath = "//user[login/text()=$login and password/text()=$password]/attribute::id"; if( file_exists($file) ) { $xml = simplexml_load_file($file); if($result = $xml->xpath($xpath)) echo "You are now logged in as user $result[0]."; else echo "Invalid login name or password."; } else exit("Failed to open $file.");?>
Никакие проверки не выполняются на вводе. Это означает, что злорадный пользователь может "закоротить" тест, входя '
or 1=1
и для имени для входа в систему и для пароля, приводящего к $xpath
быть оцененным как показано здесь:
//user[login/text()='' or 1=1 and password/text()='' or 1=1]/attribute::id
Так как выражение в квадратных скобках всегда оценивает как true
, это - эффективно
то же самое как этот, который соответствует id
атрибут каждого user
элемент в XML-документе:
//user/attribute::id
Один путь, которым может обойтись эта определенная атака, просто, заключая имена переменной в кавычки, которые
будут интерполированы в определении $xpath
, принуждение значений, которые передают
из Веб-формы, которая будет преобразована в строки:
$xpath = "//user[login/text()='$login' and password/text()='$password']/attribute::id";
Это - та же самая стратегия, которая часто рекомендуется для того, чтобы предотвратить атаки с использованием кода на SQL. Вообще, методы, за которыми следует следовать для того, чтобы предотвратить атаки инжекции XPath, являются тем же самым что касается предотвращения инжекции SQL:
Никогда принимаемые непротестированные данные от пользователей в Вашем приложении.
Проверьте все представленные пользователем данные на тип; отклоните или преобразуйте данные, которые имеют неправильный тип
Протестируйте числовые данные на из значений диапазона; усеченный, вокруг, или значения отклонения, которые испытывают недостаток диапазона. Тестовые строки для запрещенных символов и или разделяют их или отклоняют ввод, содержащий их.
Не выводите явные сообщения об ошибках, которые могли бы предоставить неавторизованному пользователю подсказки, которые могли использоваться, чтобы поставить под угрозу систему; зарегистрируйте их к файлу или таблице базы данных вместо этого.
Так же, как атаки с использованием кода на SQL могут использоваться, чтобы получить информацию о схемах базы
данных, так можете, инжекция XPath использоваться, чтобы пересечь XML-файлы, чтобы раскрыть их структуру, как
обсуждено в статье Амита Кляйна
Также важно проверить вывод, отсылаемый назад к клиенту. Рассмотрите то, что может произойти, когда мы
используем MySQL ExtractValue()
функция:
mysql>SELECT ExtractValue(
->LOAD_FILE('users.xml'),
->'//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
->) AS id;
+-------------------------------+| id |+-------------------------------+| 00327 13579 02403 42354 28570 |+-------------------------------+1 row in set (0.01 sec)
Поскольку ExtractValue()
возвраты многократные соответствия как разграниченная одинарным
интервалом строка, эта инжекционная атака обеспечивает каждый допустимый ID, содержавший в пределах users.xml
пользователю как единственная строка вывода. Как дополнительная
гарантия, следует также протестировать вывод прежде, чем возвратить это пользователю. Вот простой пример:
mysql>SELECT @id = ExtractValue(
->LOAD_FILE('users.xml'),
->'//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
->);
Query OK, 0 rows affected (0.00 sec)mysql>SELECT IF(
->INSTR(@id, ' ') = 0,
->@id,
->'Unable to retrieve user ID')
->AS singleID;
+----------------------------+| singleID |+----------------------------+| Unable to retrieve user ID |+----------------------------+1 row in set (0.00 sec)
Вообще, направляющие линии для того, чтобы возвратить данные пользователям надежно являются тем же самым что касается принятия ввода данных пользователем. Им можно подвести итог как:
Всегда тест исходящие данные для типа и допустимых значений.
Никогда не разрешайте неавторизованным пользователям просматривать сообщения об ошибках, которые могли бы предоставить информацию о приложении, которое могло использоваться, чтобы использовать ее.