2008-10-09 13 views
5

मुझे तत्व विशेषता के लिए एक XPath क्वेरी गतिशील रूप से बनाने की आवश्यकता है, जहां उपयोगकर्ता द्वारा विशेषता मान प्रदान किया जाता है। मैं निश्चित रूप से एसक्यूएल इंजेक्शन हमले के XPath समकक्ष को रोकने के लिए इस मान को साफ करने या स्वच्छ करने के बारे में अनिश्चित हूं। उदाहरण के लिए (PHP में):xpath विशेषताओं की सफाई/sanitizing

<?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'] 

विशेष रूप से अंतिम व्यक्ति एसक्यूएल इंजेक्शन हमलों के लिए याद दिलाता है।

अब, मुझे पता है कि ऐसे गुण होंगे जिनमें सिंगल कोट्स और डबल कोट्स वाले गुण होंगे। चूंकि इन्हें फ़ंक्शन के लिए तर्क के रूप में प्रदान किया जाता है, इनके लिए इनपुट को स्वच्छ करने का आदर्श तरीका क्या होगा?

उत्तर

-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}\"]"); 
} 

ठीक है, यह क्या करता है?

यह & के सभी आवृत्तियां और encodes "& amp के रूप में, और & quot;। स्ट्रिंग है, जो आप उस विशेष इस्तेमाल के लिए एक सुरक्षित चयनकर्ता देना चाहिए में ध्यान दें कि मैं भी साथ xpath में भीतरी प्रतिस्थापित '"। संपादित करें: तब से यह इंगित किया गया है कि '& apos के रूप में बच निकला जा सकता है, ताकि आप जो भी स्ट्रिंग उद्धरण विधि पसंद करते हैं उसका उपयोग कर सकें।

+0

आप शायद ' अनदेखी कर रहे हैं? –

+0

हाँ, यही वह है जिसे मैं ढूंढ रहा हूं। यहां एक्सएमएल इकाइयों के सभी (5) की एक सूची है: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references –

-1

मैं एक डोम का उपयोग कर एक एकल-तत्व XML दस्तावेज़ बनाउंगा, तत्व के पाठ को प्रदत्त मान पर सेट करने के लिए DOM का उपयोग करें, और फिर XML के DOM के स्ट्रिंग प्रस्तुति से टेक्स्ट को पकड़ लें। यह गारंटी देगा कि सभी चरित्र भागने से ठीक से किया जाता है, न केवल चरित्र से बचने के लिए जो मैं ऑफहैंड के बारे में सोचने के लिए हो रहा हूं।

संपादित करें: इस तरह की स्थितियों में डीओएम का उपयोग करने का कारण यह है कि जो लोग डीओएम लिखते हैं, उन्होंने एक्सएमएल सिफारिश पढ़ी है और मेरे पास नहीं है (कम से कम, उनके पास देखभाल के स्तर के साथ नहीं)। एक मामूली उदाहरण चुनने के लिए, डीओएम एक पार्स त्रुटि की रिपोर्ट करेगा यदि टेक्स्ट में एक ऐसा अक्षर है जो XML को अनुमति नहीं देता है (जैसे # x8), क्योंकि डीओएम के लेखकों ने XML अनुशंसा की धारा 2.2 लागू की है।

अब, मैं कह सकता हूं, "ठीक है, मुझे एक्सएमएल अनुशंसा से अमान्य वर्णों की सूची मिल जाएगी, और उन्हें इनपुट से बाहर कर दिया जाएगा।" ज़रूर। चलो बस एक्सएमएल सिफारिश देखें और ... उम, यूनिकोड सरोगेट ब्लॉक क्या बिल्ली हैं? उनसे छुटकारा पाने के लिए मुझे किस तरह का कोड लिखना है? क्या वे पहले भी मेरे पाठ में आ सकते हैं?

मान लीजिए कि मैं इसे समझता हूं। क्या एक्सएमएल सिफारिश कैसे चरित्र प्रतिनिधित्व को निर्दिष्ट करती है, इसके बारे में अन्य पहलू हैं जिनके बारे में मुझे नहीं पता? शायद। क्या इसका प्रभाव उन पर असर डालेगा जो मैं लागू करने की कोशिश कर रहा हूं? शायद।

यदि मैं डोम को मेरे लिए चरित्र एन्कोडिंग करने देता हूं, तो मुझे उस सामान के बारे में चिंता करने की ज़रूरत नहीं है।

+0

यह काम नहीं करेगा। डोम '0 के रूप में' –

+0

का प्रतिनिधित्व करेगा हां, यह होगा। यदि आप .NET DOM का उपयोग करते हैं, उदाहरण के लिए, XmlElement की InnerXml प्रॉपर्टी तत्व टेक्स्ट का मार्कअप देता है। जैसा कि आप वर्णन करते हैं इसकी मूल्य संपत्ति व्यवहार करती है। –

+0

लेकिन वह PHP बात कर रहा है, और मुझे इसका समर्थन करने के लिए (खराब) दस्तावेज में कुछ भी नहीं दिख रहा है। –

5

XPath वास्तव में इसे सुरक्षित रूप से करने का एक तरीका शामिल करता है, जिसमें यह variable references को अभिव्यक्तियों में $varname रूप में अनुमति देता है। लाइब्रेरी जिस पर PHP का SimpleXML 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"') 

ध्यान दें, यदि आप एक XML दस्तावेज़ के रूप &apos; बाहर में भागने उपयोग नहीं कर सकते, और न ही सामान्य एक्सएमएल क्रमबद्धता दिनचर्या लागू होते हैं। हालांकि, XPath concat फ़ंक्शन का उपयोग किसी भी संदर्भ में दोनों प्रकार के उद्धरणों के साथ एक स्ट्रिंग बनाने के लिए किया जा सकता है।

पीएचपी संस्करण:

function safe_xpath_string($value) 
{ 
    $quote = "'"; 
    if (FALSE === strpos($value, $quote)) 
     return $quote.$value.$quote; 
    else 
     return sprintf("concat('%s')", implode("', \"'\", '", explode($quote, $value))); 
}