2008-10-09 6 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}\"]"); 
} 

좋아, 어떻게합니까?

그것은 모든 &의 발행 수와 인코딩 "& A로하고, & quot;. 당신에게 특정 사용하기에 안전한 선택을 제공한다 문자열에서 나는 또한과는 XPath에서 '내부를 대체합니다." 편집 : 그 이후로 '도망 수있는 지적했다 & apos, 그래서 당신이 선호하는 문자열 인용 방법을 사용할 수 있습니다.

+0

당신은 아마도 ' 내려다 보이는 있습니까? –

+0

그래, 그게 내가 찾고있는거야. 다음 XML 엔티티 목록이 모두 있습니다 (http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references –

-1

DOM을 사용하여 단일 요소 XML 문서를 만들고 DOM을 사용하여 요소의 텍스트를 제공된 값으로 설정 한 다음 XML의 DOM 문자열 표현에서 텍스트를 가져온다. 이렇게하면 모든 캐릭터가 이스케이프 처리가 제대로 수행되고 캐릭터가 벗어나서 내가 오프 쉐이크에 대해 생각하고 있다고 보장 할 수 있습니다.

편집 : 내가 이런 상황에서 DOM을 사용하는 이유는 DOM을 작성한 사람들이 XML 권장 사항을 읽었으며 최소한 (가지고있는주의 수준과는 다른) XML을 읽지 못했기 때문입니다. 간단한 예제를 선택하기 위해 DOM 작성자가 XML 권고 섹션 2.2를 구현했기 때문에 XML에 허용되지 않는 문자 (예 : # x8)가 텍스트에 포함되어 있으면 DOM에서 구문 분석 오류를보고합니다.

이제 "XML 권장 사항에서 유효하지 않은 문자 목록을 가져 와서 입력에서 제외합니다."라고 말할 수 있습니다. 확실한. XML 권장 사항을 살펴보고 ... 음, 유니 코드 사로 게이트 블록은 무엇일까? 코드를 제거하려면 어떤 종류의 코드를 작성해야합니까? 그들은 심지어 내 텍스트에 들어갈 수 있습니까?

내가 알아 냈다고 가정 해 봅시다. XML 권고에서 내가 모르는 문자 표현을 지정하는 방법에 대한 다른 측면이 있습니까? 아마. 이것들이 내가 구현하려는 것에 영향을 미칠 것인가? 아마도.

DOM이 나를 위해 문자 인코딩을하도록 내버려두면, 그 어떤 것도 걱정할 필요가 없습니다.

+0

).이 기능은 작동하지 않습니다. dom은 'a'로 표시됩니다. –

+0

예, 가능합니다. 예를 들어 .Net DOM을 사용하는 경우 XmlElement의 InnerXml 속성은 요소 텍스트의 태그를 반환합니다. Value 속성은 사용자가 설명하는대로 동작합니다. –

+0

하지만 그는 PHP에 대해 이야기하고 있으며, (가난한) 문서에서 아무것도 지원하지 않습니다. –

5

XPath에는 실제로 $varname 형식의 variable references이 허용된다는 점에서이 작업을 안전하게 수행하는 방법이 포함되어 있습니다. PHP의 SimpleXML 기반 라이브러리는 provides an interface to supply variables이지만이 예에서는 is not exposed by the xpath function입니다. 이 될 수 정말 얼마나 간단한의 데모로

: 비슷한 xpath function로, lxml, SimpleXML을 같은 기본 라이브러리에 대한 파이썬 래퍼를 사용하고

>>> 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 

. 부울, 숫자 및 노드 집합도 직접 전달할 수 있습니다.

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

반환 값 할 수 있습니다

더 할 수 XPath를 인터페이스로 전환하는의 라인을 따라 옵션, 주어진 외부 문자열이 뭔가 (PHP에 적응 주시기를) 할 것입니다 해결되지 않으면

표현식 문자열에 직접 삽입 할 수 있습니다. 그것은 실제로 매우 읽을 수 없습니다의로, 여기가 작동하는 방법입니다

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

주, 당신은 XML 문서의 형태로 &apos; 외부에서 탈출 사용할 수 없으며, 일반적인 XML 직렬화 루틴이 적용됩니다. 그러나 XPath concat 함수는 모든 컨텍스트에서 두 가지 유형의 따옴표가있는 문자열을 만드는 데 사용할 수 있습니다.

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))); 
}