2008-10-09 4 views
5

Мне нужно динамически построить запрос XPath для атрибута элемента, где значение атрибута предоставляется пользователем. Я не уверен, как сделать очистку или дезинформировать это значение, чтобы предотвратить эквивалент XPath атаки SQL-инъекции. Например (в PHP):Очистка/дезинфекция атрибутов xpath

<?php 
function xPathQuery($attr) { 
    $xml = simplexml_load_file('example.xml'); 
    return $xml->xpath("//myElement[@content='{$attr}']"); 
} 

xPathQuery('This should work fine'); 
# //myElement[@content='This should work fine'] 

xPathQuery('As should "this"'); 
# //myElement[@content='As should "this"'] 

xPathQuery('This\'ll cause problems'); 
# //myElement[@content='This'll cause problems'] 

xPathQuery('\']/../privateElement[@content=\'private data'); 
# //myElement[@content='']/../privateElement[@content='private data'] 

Последние, в частности, напоминает инъекцию SQL атак былого.

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

ответ

-1
function xPathQuery($attr) { 
    $xml = simplexml_load_file('example.xml'); 
    $to_encode = array('&', '"'); 
    $to_replace = array('&amp;','&quot;'); 
    $attr = replace($to_encode, $to_replace, $attr); 
    return $xml->xpath("//myElement[@content=\"{$attr}\"]"); 
} 

Хорошо, что он делает?

Он кодирует все вхождений & и «в качестве & усилителя и & Quot;. В строке, которая должна дать вам безопасный селектор для конкретного использования Обратите внимание, что я также заменил внутренний" в XPath с». EDIT: С тех пор было указано, что «можно избежать как & apos ;, так что вы можете использовать любой тип строкового цитирования, который вы предпочитаете.

+0

Вы, возможно, с видом '? – 2008-10-10 04:41:10

+0

Да, это тот, который я ищу. Здесь есть список всех (5) объектов XML: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references – 2008-10-10 11:45:43

-1

Я создаю одноэлементный XML-документ с использованием DOM, использую DOM, чтобы установить текст элемента в предоставленное значение, а затем извлечь текст из строкового представления DOM XML. Это гарантирует, что все экранирование персонажа будет выполнено правильно, а не только персонаж, с которым я сталкиваюсь, чтобы думать об этом.

Редактировать: Причина, по которой я буду использовать DOM в таких ситуациях, что люди, которые написали DOM, прочитали рекомендацию XML, и у меня нет (по крайней мере, не с уровнем ухода, который у них есть). Чтобы выбрать тривиальный пример, DOM сообщит об ошибке синтаксического анализа, если текст содержит символ, который не разрешает XML (например, # x8), поскольку авторы DOM внедрили раздел 2.2 рекомендации XML.

Теперь я могу сказать: «Хорошо, я просто получу список недопустимых символов из рекомендации XML и вычеркнул их из ввода». Конечно. Давайте просто посмотрим на рекомендацию XML и ... гм, каковы черты суррогатных блоков Unicode? Какой код мне нужно написать, чтобы избавиться от них? Могут ли они даже попасть в мой текст в первую очередь?

Предположим, я это понял. Существуют ли другие аспекты того, как рекомендации XML указывают представления символов, о которых я не знаю? Вероятно. Будут ли они влиять на то, что я пытаюсь реализовать? Может быть.

Если я позволю DOM сделать кодировку символов для меня, мне не нужно беспокоиться об этом.

5

XPath действительно включает в себя способ безопасного выполнения, поскольку он позволяет variable references в форме $varname в выражениях. Библиотека, на которой основан SimpleXML PHP, находится provides an interface to supply variables, однако это is not exposed by the xpath function в вашем примере.

В качестве демонстрации действительно, как просто это может быть:

>>> from lxml import etree 
>>> n = etree.fromstring('<n a=\'He said "I&apos;m here"\'/>') 
>>> n.xpath("@a=$maybeunsafe", maybeunsafe='He said "I\'m here"') 
True 

Это использует lxml, питон обертку для одной и той же базовой библиотеки как SimpleXML, с подобным xpath function. Булевы, числа и наборы узлов также могут передаваться напрямую.

Если переключение на более способного интерфейс XPath не вариант, обходной путь, когда дается внешняя строка будет что-то (не стесняйтесь, чтобы адаптироваться к PHP) по линиям:

def safe_xpath_string(strvar): 
    if "'" in strvar: 
     return "',\"'\",'".join(strvar.split("'")).join(("concat('","')")) 
    return strvar.join("''") 

возвращаемое значение может быть непосредственно вставленным в строку выражения. Как это на самом деле не очень читаемый, вот как он себя ведет:

>>> print safe_xpath_string("basic") 
'basic' 
>>> print safe_xpath_string('He said "I\'m here"') 
concat('He said "I',"'",'m here"') 

Обратите внимание, вы не можете использовать побег в виде &apos; снаружи документа XML, ни родовые XML сериализации процедуры применимы. Тем не менее, функция concath XPath может использоваться для создания строки с обоими типами котировок в любом контексте.

PHP вариант:

function safe_xpath_string($value) 
{ 
    $quote = "'"; 
    if (FALSE === strpos($value, $quote)) 
     return $quote.$value.$quote; 
    else 
     return sprintf("concat('%s')", implode("', \"'\", '", explode($quote, $value))); 
} 
Смежные вопросы