2010-05-14 9 views
5

कई स्टैक ओवरफ़्लो सवाल (जैसे Whitelisting, preventing XSS with WMD control in C# और WMD Markdown and server-side) कैसे Markdown के सर्वर साइड स्क्रबिंग द्वारा उत्पादित क्या करने वाले हैं सामूहिक नरसंहार के हथियारों संपादक एचटीएमएल उत्पन्न दुर्भावनापूर्ण स्क्रिप्ट शामिल नहीं है, इस तरह सुनिश्चित करने के लिए:सामूहिक नरसंहार के हथियारों संपादक का पूर्वावलोकन सर्वर साइड HTML सत्यापन के साथ HTML (जैसे कोई एम्बेडेड जावा स्क्रिप्ट कोड) संरेखित

<img onload="alert('haha');" 
    src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" /> 

लेकिन मैं भी क्लाइंट की तरफ छेद प्लग करने के लिए एक अच्छा तरीका नहीं मिला। क्लाइंट सत्यापन पाठ्यक्रम के सर्वर पर सत्यापन को स्क्रब करने के लिए प्रतिस्थापन नहीं है, क्योंकि कोई भी ग्राहक बनने का नाटक कर सकता है और आपको खराब मार्कडाउन पोस्ट कर सकता है। और यदि आप सर्वर पर HTML को स्क्रब कर रहे हैं, तो हमलावर खराब HTML को सहेज नहीं सकता है, इसलिए कोई भी इसे बाद में नहीं देख पाएगा और अपनी कुकीज़ चोरी हो जाएगी या खराब स्क्रिप्ट द्वारा सत्रों को अपहरण कर लिया जाएगा। तो एक वैध मामला बनना है कि यह डब्लूएमडी पूर्वावलोकन फलक में भी नो-स्क्रिप्ट नियमों को लागू करने योग्य नहीं हो सकता है।

लेकिन कल्पना करें कि एक हमलावर को सर्वर पर दुर्भावनापूर्ण मार्कडाउन प्राप्त करने का एक तरीका मिला है (उदाहरण के लिए किसी अन्य साइट से एक समझौता फ़ीड, या एक्सएसएस बग से पहले जोड़ा गया सामग्री)। एचटीएमएल में मार्कडाउन का अनुवाद करते समय आपके सर्वर-साइड श्वेतसूची लागू होती है जो आम तौर पर उस खराब मार्कडाउन को उपयोगकर्ताओं को दिखाए जाने से रोकती है। लेकिन अगर हमलावर किसी को पृष्ठ को संपादित करने के लिए प्राप्त कर सकता है (उदाहरण के लिए एक और प्रविष्टि पोस्ट करके कह रही है कि दुर्भावनापूर्ण प्रविष्टि में टूटा हुआ लिंक था और किसी को इसे ठीक करने के लिए कहा गया था), तो पृष्ठ को संपादित करने वाले किसी भी व्यक्ति को उनकी कुकीज़ को अपहरण कर लिया जाता है। यह स्वीकार्य रूप से एक कोने का मामला है, लेकिन यह अभी भी बचाव के लायक हो सकता है।

साथ ही, क्लाइंट पूर्वावलोकन विंडो को आपके सर्वर की अनुमति देने से अलग HTML की अनुमति देने की अनुमति देने का शायद एक बुरा विचार है।

स्टैक ओवरफ़्लो टीम ने डब्लूएमडी में परिवर्तन करके इस छेद को प्लग किया है। उन्होंने यह कैसे किया?

[नोट: मैंने इसे पहले से ही समझ लिया है, लेकिन इसे कुछ मुश्किल जावास्क्रिप्ट डिबगिंग की आवश्यकता है, इसलिए मैं उन लोगों की मदद करने के लिए यहां अपने स्वयं के प्रश्न का उत्तर दे रहा हूं जो एक ही चीज करना चाहते हैं]

उत्तर

6

pushPreviewHtml() विधि में, एक संभावित फिक्स wmd.js में है। यहाँ Stack Overflow version of WMD on GitHub से मूल कोड है:

if (wmd.panels.preview) { 
    wmd.panels.preview.innerHTML = text; 
} 

आप कुछ स्क्रबिंग कोड से बदल सकते हैं। यहां कोड का एक अनुकूलन है जो स्टैक ओवरफ़्लो in response to this post का उपयोग करता है, जो टैग की श्वेतसूची में प्रतिबंधित होता है, और आईएमजी और ए तत्वों के लिए, गुणों की श्वेतसूची (और एक विशिष्ट क्रम में भी) पर प्रतिबंध लगाता है। श्वेतसूची पर अधिक जानकारी के लिए मेटा स्टैक ओवरफ़्लो पोस्ट What HTML tags are allowed on Stack Overflow, Server Fault, and Super User? देखें।

नोट: यह कोड निश्चित रूप से सुधार किया जा सकता है, उदा। किसी भी क्रम में श्वेतसूची वाले गुणों की अनुमति देने के लिए। यह मेलto को भी अस्वीकार करता है: यूआरएल जो शायद इंटरनेट साइटों पर एक अच्छी बात है लेकिन आपकी खुद की इंट्रानेट साइट पर यह सबसे अच्छा तरीका नहीं हो सकता है।

if (wmd.panels.preview) { 

    // Original WMD code allowed JavaScript injection, like this: 
    // <img src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" onload="alert('haha');"/> 
    // Now, we first ensure elements (and attributes of IMG and A elements) are in a whitelist, 
    // and if not in whitelist, replace with blanks in preview to prevent XSS attacks 
    // when editing malicious Markdown. 
    var okTags = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i; 
    var okLinks = /^(<a\shref="(\#\d+|(https?|ftp):\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+)"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i; 
    var okImg = /^(<img\ssrc="https?:(\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+)"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i; 
    text = text.replace(/<[^<>]*>?/gi, function (tag) { 
     return (tag.match(okTags) || tag.match(okLinks) || tag.match(okImg)) ? tag : "" 
    }) 

    wmd.panels.preview.innerHTML = text; // Original code 
} 

भी ध्यान रखें कि यह सुधार Stack Overflow version of WMD on GitHub में नहीं है - स्पष्ट रूप से परिवर्तन बाद में और नहीं किया गया था GitHub में वापस जाँच की।

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

मूल कोड:

var _DoAutoLinks = function(text) { 

    text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>"); 

    // Email addresses: <[email protected]> 

    /* 
     text = text.replace(/ 
      < 
      (?:mailto:)? 
      (
       [-.\w]+ 
       \@ 
       [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ 
      ) 
      > 
     /gi, _DoAutoLinks_callback()); 
    */ 
    text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 
     function(wholeMatch,m1) { 
      return _EncodeEmailAddress(_UnescapeSpecialChars(m1)); 
     } 
    ); 

    return text; 
} 

फिक्स्ड कोड:

var _DoAutoLinks = function(text) { 
    // use simplified format for links, to enable whitelisting link attributes 
    text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4"); 
    text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, '<a href="$1">$1</a>'); 
    return text; 
} 
+0

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

+2

हां, मुझे विश्वास नहीं है कि इसकी आवश्यकता भी है। उस ने कहा, StackOverflow.com लोगों ने यह सुनिश्चित करने के लिए इसे कार्यान्वित किया कि पूर्वावलोकनकर्ता ने कभी भी HTML उत्पन्न नहीं किया है कि उनके सर्वर-साइड सत्यापनकर्ता स्वीकार नहीं करेंगे। उचित लगता है, हालांकि मैं बहुत अधिक प्राथमिकता से सहमत नहीं हूं। ऐसा क्यों किया गया है इसके बारे में अधिक जानकारी के लिए http://meta.stackexchange.com/questions/1227/preview-should-match-the- पोस्ट किया गया- देखें। बीटीडब्ल्यू मैंने अपने प्रश्न को वास्तविक कारण के साथ संरेखित करने के लिए संपादित किया है कि एसओ ऐसा करना चाहता था। –

+0

आप AJAX पोस्ट कर सकते हैं और एक पूर्ण पूर्वावलोकन प्राप्त करने के लिए, सर्वर से sanitized HTML वापस प्राप्त कर सकते हैं। – ceejayoz

2

यह स्थानीय उपयोगकर्ता में आलेख निष्पादित करने की अनुमति के लिए एक सुरक्षा मुद्दा नहीं है पेज संदर्भ जब तक किसी तीसरे पक्ष के लिए स्क्रिप्ट प्रदान करना असंभव है। संपादक के बिना, उपयोगकर्ता हमेशा आपके पृष्ठ पर javascript: यूआरएल दर्ज कर सकता है या फ़ायरबग या कुछ इसी तरह का उपयोग कर सकता है।

+0

शुरुआत में मैंने आपके साथ सहमति व्यक्त की, लेकिन मुझे एक दिलचस्प मामला मिला: यदि किसी हमलावर के लिए सर्वर पर समझौता किए गए मार्कडाउन के लिए कोई और तरीका था, तो यह डब्लूएमडी पूर्वावलोकन समस्या खतरनाक होगी। यदि कोई हमलावर खराब पृष्ठ को संपादित करने के लिए साइट मॉडरेटर प्राप्त कर सकता है (उदा। टूटा हुआ लिंक साफ़ करने के लिए), तो वह संभवतः पूरी साइट पर नियंत्रण ले सकता है। सच है, संपादन पृष्ठ पर भेजने से पहले सर्वर पर मार्कडाउन स्क्रब करके हारना आसान हो सकता है, लेकिन आउटपुट सत्यापन अक्सर अनदेखा किया जाता है। यह स्वीकार्य रूप से एक कोने का मामला है, लेकिन एक सुरक्षित साइट के खिलाफ बचाव के लायक हो सकता है। –