प्रतिनिधि इंटरव्यू विषय

Frontend Interview: वेब एप्लिकेशन में XSS को कैसे रोकें?

फ्रंटएंडकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक React कम्युनिटी एप्लिकेशन सामान्य टिप्पणियों को सादे टेक्स्ट के रूप में प्रदर्शित करता है, जबकि मॉडरेटर की घोषणाओं में रिच-टेक्स्ट टैग और लिंक का एक सीमित सेट हो सकता है। एक सुरक्षा समीक्षा में पाया गया कि उपयोगकर्ता डेटा dangerouslySetInnerHTML और innerHTML तक पहुँच रहा है, और location.search से एक सर्च क्वेरी को परिणाम बैनर में डाला गया है। बताएं कि आप स्टोर्ड, रिफ्लेक्टेड और DOM-आधारित XSS जोखिमों की पहचान कैसे करेंगे, प्रत्येक रेंडरिंग पाथ को फिर से डिज़ाइन कैसे करेंगे, डिफेंस-इन-डेप्थ नियंत्रण कैसे जोड़ेंगे और यह कैसे सत्यापित करेंगे कि समाधान काम कर रहा है।

समस्या और यह कब लागू होती है

एक React कम्युनिटी एप्लिकेशन में तीन रेंडरिंग पाथ हैं:

  • सामान्य टिप्पणियाँ डेटाबेस में संग्रहीत होती हैं और उन्हें पूरी तरह से टेक्स्ट के रूप में दिखना चाहिए।
  • मॉडरेटर की घोषणाएँ एक सीमित रिच-टेक्स्ट शब्दावली का उपयोग कर सकती हैं: पैराग्राफ, एम्फैसिस (emphasis), सूचियाँ और HTTPS लिंक।
  • एक खोज पृष्ठ location.search से q पढ़ता है और सर्वर-रेंडर की गई प्रतिक्रिया की प्रतीक्षा किए बिना "Results for …" प्रदर्शित करता है।

एक समीक्षा में पाया गया कि सामान्य टिप्पणियाँ और घोषणा पूर्वावलोकन dangerouslySetInnerHTML या innerHTML में जा रहे हैं। खोज बैनर भी क्वेरी को एक HTML स्ट्रिंग में जोड़ता है। बताएं कि प्रत्येक सोर्स-टू-सिंक पाथ को कैसे खोजा जाए, हमले के जीवन चक्रों में अंतर कैसे किया जाए, प्रत्येक संदर्भ के लिए एन्कोडिंग या सैनिटाइजेशन कैसे चुना जाए, और ऐसे नियंत्रण कैसे जोड़े जाएं जो छूटे हुए सिंक के प्रभाव को कम करते हैं।

बुनियादी उत्तर ब्राउज़र रेंडरिंग और फ्रंटएंड स्वामित्व को कवर करता है। सर्वर-साइड सत्यापन, प्राधिकरण और सामग्री भंडारण आवश्यक सीमाएं बनी हुई हैं, लेकिन वे एक असुरक्षित DOM सिंक को सुरक्षित नहीं बनाते हैं। यह एक फ्रंटएंड प्रश्न है क्योंकि निर्णायक कौशल ब्राउज़र पार्सिंग, फ्रेमवर्क एस्केप हैच, DOM इंजेक्शन सिंक, CSP और परीक्षण योग्य रेंडरिंग अनुबंधों को समझना है।

स्टोर्ड, रिफ्लेक्टेड और DOM-आधारित उपयोगी लेबल हैं, लेकिन वे विभिन्न अक्षों का वर्णन करते हैं। "स्टोर्ड" और "रिफ्लेक्टेड" वर्णन करते हैं कि हमलावर-नियंत्रित डेटा पीड़ित तक कैसे पहुँचता है। "DOM-आधारित" क्लाइंट-साइड निष्पादन पथ का वर्णन करता है जिसमें JavaScript डेटा को एक इंजेक्शन सिंक में ले जाता है। एक स्टोर्ड या रिफ्लेक्टेड पेलोड अभी भी एक DOM सिंक के माध्यम से निष्पादित हो सकता है, इसलिए ये लेबल हमेशा परस्पर अनन्य नहीं होते हैं।

साक्षात्कारकर्ता क्या मूल्यांकन कर रहा है

पहला संकेत यह है कि क्या उम्मीदवार सुरक्षा हेडर सूचीबद्ध करने से पहले डेटा-फ्लो सीमा खींचता है। एक मजबूत उत्तर डेटाबेस फ़ील्ड, URL पैरामीटर, फ़्रैगमेंट, postMessage और तृतीय-पक्ष प्रतिक्रियाओं जैसे स्रोतों की पहचान करता है, फिर innerHTML, outerHTML, insertAdjacentHTML, document.write, eval और स्ट्रिंग-आधारित टाइमर जैसे सिंक की पहचान करता है। सवाल यह बन जाता है: क्या हमलावर-नियंत्रित डेटा ऐसे पार्सर तक पहुँच सकता है जो इसे मार्कअप, स्क्रिप्ट या स्क्रिप्ट URL मानता है?

दूसरा संकेत इच्छित डेटा प्रकार से रक्षा का चयन करना है। सादी टिप्पणियाँ टेक्स्ट हैं, इसलिए उन्हें एक टेक्स्ट सिंक या सामान्य JSX इंटरपोलेशन तक पहुँचना चाहिए। रिच घोषणाओं में जानबूझकर HTML होता है, इसलिए एंटिटी एन्कोडिंग सुविधा को तोड़ देगी; उन्हें विश्वसनीय रेंडरिंग सीमा से ठीक पहले एक संकीर्ण नीति के साथ एक अनुरक्षित HTML सैनिटाइज़र की आवश्यकता होती है। URL मानों को सही आउटपुट संदर्भ के अलावा प्रोटोकॉल और गंतव्य सत्यापन की आवश्यकता होती है।

तीसरा संकेत यह है कि क्या उम्मीदवार फ्रेमवर्क की सीमाओं को समझता है। React सामान्य स्ट्रिंग इंटरपोलेशन से एस्केप करता है, लेकिन dangerouslySetInnerHTML एक स्पष्ट एस्केप हैच है। एक फ्रेमवर्क किसी अपरिष्कृत HTML स्ट्रिंग को बचा नहीं सकता है या किसी खतरनाक प्रॉपर्टी को आपूर्ति किए गए प्रत्येक javascript: या data: URL को मान्य नहीं कर सकता है।

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

उत्तर देने से पहले स्पष्ट करने वाले प्रश्न

  • कौन से फ़ील्ड टेक्स्ट हैं और कौन से फ़ील्ड में जानबूझकर HTML शामिल है? यदि प्रत्येक फ़ील्ड टेक्स्ट है, तो सभी अपरिष्कृत

HTML रेंडरिंग हटा दें। यदि घोषणाओं को फ़ॉर्मेटिंग की आवश्यकता है, तो सैनिटाइज़र चुनने से पहले एक सटीक टैग, विशेषता (attribute) और URL नीति परिभाषित करें।

  • घोषणाएँ कौन लिख सकता है? केवल-मॉडरेटर इनपुट जोखिम को कम करता है लेकिन इसे विश्वसनीय नहीं बनाता है। एक चोरी हुआ

मॉडरेटर सत्र, समझौता किया गया आयात, माइग्रेशन या API बग अभी भी दुर्भावनापूर्ण सामग्री को बनाए रख सकता है।

  • क्या घोषणा लिंक को साइट छोड़ने की अनुमति है? आधार समाधान केवल HTTPS लिंक की अनुमति देता है। मेल,

कस्टम प्रोटोकॉल, छवियों, वीडियो या एम्बेडेड फ़्रेम की अनुमति देने के लिए एक व्यापक नीति और अतिरिक्त अलगाव की आवश्यकता होती है।

  • आज सैनिटाइजेशन कहाँ किया जाता है? राइट-टाइम सैनिटाइजेशन खराब इनपुट को जल्दी अस्वीकार कर सकता है, लेकिन

रेंडरिंग सीमा को अभी भी इस गारंटी की आवश्यकता है कि अपरिष्कृत HTML सिंक तक पहुँचने वाले प्रत्येक मान को वर्तमान नीति द्वारा सैनिटाइज किया गया था।

  • किन ब्राउज़रों का समर्थन किया जाना चाहिए? CSP व्यापक रूप से उपयोगी है। Trusted Types समर्थन और रोलआउट व्यवहार को

वास्तविक ब्राउज़र मैट्रिक्स के विरुद्ध जाँचा जाना चाहिए; असमर्थित क्लाइंट अभी भी सुरक्षित सिंक और सैनिटाइजेशन पर निर्भर करते हैं।

  • किन तृतीय-पक्ष स्क्रिप्ट की आवश्यकता है? जब एप्लिकेशन में एक छोटा,

ऑडिट किया गया स्क्रिप्ट सेट होता है तो एक सख्त स्क्रिप्ट नीति आसान होती है। टैग मैनेजर और इनलाइन स्निपेट CSP माइग्रेशन योजना को बदलते हैं और किसी भी सफल XSS के प्रभाव का विस्तार करते हैं।

  • परिचालन के संदर्भ में "ठीक किया गया" का क्या अर्थ है? उत्तर में रिग्रेशन परीक्षण, CSP उल्लंघन निगरानी,

सैनिटाइज़र अपडेट, नीति परिवर्तनों का स्वामित्व और नए पेश किए गए सिंक को खोजने की एक विधि शामिल होनी चाहिए।

30-सेकंड उत्तर ढांचा

"मैं अविश्वसनीय स्रोतों और निष्पादन योग्य सिंक की एक सूची बनाऊंगा, फिर मान के इच्छित प्रकार के अनुसार प्रत्येक पाथ को ठीक करूँगा। सामान्य टिप्पणियाँ और खोज क्वेरी टेक्स्ट हैं, इसलिए React इंटरपोलेशन या textContent को HTML पार्सिंग के बिना उन्हें रेंडर करना चाहिए। घोषणा सुविधा को वास्तव में सीमित HTML की आवश्यकता है, इसलिए मैं इसे एक अनुरक्षित अनुमति-सूची (allowlist) सैनिटाइज़र के माध्यम से भेजूंगा और एक संकीर्ण रिच-टेक्स्ट रेंडरर प्रदर्शित करूँगा; लिंक को प्रोटोकॉल सत्यापन भी मिलता है। मैं अन्य innerHTML कॉल हटाऊंगा, प्रवर्तन से पहले रिपोर्ट-ओनली मोड में एक नॉन- या हैश-आधारित CSP लागू करूँगा, और DOM सिंक पर अपरिष्कृत स्ट्रिंग्स को अस्वीकार करने के लिए जहाँ ब्राउज़र मैट्रिक्स इसका समर्थन करता है, वहां Trusted Types का उपयोग करूँगा। अंत में मैं स्टोर्ड, URL-संचालित, विकृत मार्कअप, इवेंट-हैंडलर, SVG और स्क्रिप्ट-URL पेलोड का परीक्षण करूँगा और यह भी जाँचूँगा कि अनुमत फ़ॉर्मेटिंग अभी भी काम कर रही है।"

चरण-दर-चरण गहन विश्लेषण

चरण 1: प्रत्येक स्रोत को प्रत्येक पार्सिंग सिंक से मैप करें

पेलोड स्ट्रिंग्स की सूची के बजाय एक छोटी डेटा-फ्लो तालिका से शुरुआत करें:

पाथहमलावर-नियंत्रित स्रोतवर्तमान सिंकइच्छित प्रकारआवश्यक परिवर्तन
टिप्पणी कार्डडेटाबेस टिप्पणी मुख्य भागअपरिष्कृत HTML रेंडररटेक्स्टJSX इंटरपोलेशन या textContent
घोषणाडेटाबेस घोषणा मुख्य भागअपरिष्कृत HTML रेंडररसीमित HTMLअनुमति-सूची सैनिटाइजेशन, फिर एक समीक्षित सिंक
खोज बैनरlocation.searchHTML स्ट्रिंग संयोजन (concatenation)टेक्स्टtextContent या एक टेक्स्ट React चाइल्ड
घोषणा लिंकरिच-टेक्स्ट hrefURL-युक्त विशेषताHTTPS URLपार्स करें, प्रोटोकॉल मान्य करें, और विशेषता को सैनिटाइज करें

रिपॉजिटरी समीक्षा में प्रत्यक्ष सिंक और उनके चारों ओर के रैपर की खोज करनी चाहिए। safeHtml जैसे नाम प्रमाण नहीं हैं; मान को उस परिवर्तन तक ट्रेस करें जिसने इसे बनाया था। अप्रत्यक्ष प्रवेश बिंदुओं का भी निरीक्षण करें: Markdown रेंडरर, रिच-टेक्स्ट एडिटर, पूर्वावलोकन घटक, मार्कअप के साथ स्थानीयकरण संदेश, DOM पार्सर कॉल, SVG, टेम्पलेट उपयोगिताएँ, एनालिटिक्स स्निपेट, और कोड जो पृष्ठ में URL या संदेश डेटा की प्रतिलिपि बनाता है।

पाथ ज्ञात होने के बाद घटनाओं को वर्गीकृत करें:

  • डेटाबेस में संग्रहीत और अन्य उपयोगकर्ताओं को दिखाई गई एक दुर्भावनापूर्ण टिप्पणी का जीवन चक्र स्टोर्ड होता है।
  • तत्काल सर्वर प्रतिक्रिया में कॉपी किए गए अनुरोध पैरामीटर का जीवन चक्र रिफ्लेक्टेड होता है।
  • क्लाइंट JavaScript द्वारा पढ़ी गई और innerHTML को दी गई एक क्वेरी या फ़्रैगमेंट में DOM-आधारित निष्पादन पथ होता है।

यह वर्गीकरण घटना प्रतिक्रिया में मदद करता है, लेकिन सुधार का निर्णय अभी भी स्रोत, आउटपुट संदर्भ और सिंक से आता है।

चरण 2: टेक्स्ट को टेक्स्ट ही रहने दें

सामान्य टिप्पणियों और खोज लेबल को मार्कअप की आवश्यकता नहीं होती है। सामान्य React चिल्ड्रन का उपयोग करें:

tsx
function CommentBody({ body }: { body: string }) {
  return <p>{body}</p>
}

function SearchSummary({ query }: { query: string }) {
  return <p>Results for “{query}”</p>
}

React के बाहर, एक टेक्स्ट सिंक का उपयोग करें:

typescript
summaryNode.textContent = query

ब्राउज़र अब डेटा को HTML के रूप में फिर से पार्स करने के बजाय टेक्स्ट के रूप में प्राप्त करता है। स्ट्रिंग को एक नियमित अभिव्यक्ति (regular expression) के साथ "साफ" न करें और इसे innerHTML को सौंपना जारी न रखें; HTML पार्सिंग में बहुत सारे तत्व, विशेषताएँ, एन्कोडिंग और विकृत-इनपुट रिकवरी नियम हैं जिनके कारण यह दृष्टिकोण विश्वसनीय नहीं हो सकता है।

संदर्भ अभी भी मायने रखता है। टेक्स्ट सुरक्षा स्वचालित रूप से किसी मान को इवेंट हैंडलर, स्क्रिप्ट ब्लॉक, CSS नियम या URL में सुरक्षित नहीं बनाती है। निष्पादन योग्य संदर्भों में अविश्वसनीय मान रखने से बचें। जब कोई मान किसी सुरक्षित विशेषता में आता है, तो विशेषता नाम को हार्डकोड करें और उस विशेषता द्वारा आवश्यक सत्यापन लागू करने के बाद ही फ्रेमवर्क प्रॉपर्टी या setAttribute का उपयोग करें।

चरण 3: उस एक सुविधा को अलग करें जिसके लिए HTML की आवश्यकता है

घोषणा आवश्यकता सादे टेक्स्ट का उपयोग नहीं कर सकती क्योंकि चयनित फ़ॉर्मेटिंग को जीवित रहना चाहिए। कार्यान्वयन से पहले नीति परिभाषित करें:

  • अनुमत टैग: पैराग्राफ, स्ट्रॉन्ग एम्फैसिस, एम्फैसिस, अनऑर्डर्ड और ऑर्डर्ड सूचियाँ, सूची आइटम और एंकर।
  • अनुमत विशेषताएँ: केवल href, title, और रेंडरर द्वारा जोड़ी गई लिंक विशेषताएँ।
  • आधार परिदृश्य में अनुमत लिंक प्रोटोकॉल: HTTPS।
  • अस्वीकृत सामग्री: स्क्रिप्ट, इवेंट-हैंडलर विशेषताएँ, इनलाइन शैलियाँ, फ़्रेम, फ़ॉर्म, SVG और मनमाना मीडिया।

फिर अपरिष्कृत HTML सिंक को केंद्रीकृत करें:

tsx
function RichAnnouncement({ dirtyHtml }: { dirtyHtml: string }) {
  const cleanHtml = sanitizeRichText(dirtyHtml, RICH_TEXT_POLICY)
  return <div dangerouslySetInnerHTML={{ __html: cleanHtml }} />
}

sanitizeRichText उस नीति के साथ कॉन्फ़िगर किए गए एक अनुरक्षित, पार्सर-आधारित सैनिटाइज़र का प्रतिनिधित्व करता है। OWASP एक विकल्प के रूप में DOMPurify की अनुशंसा करता है। सुरक्षा विशेषता सैनिटाइज़र और उसके कॉन्फ़िगरेशन से आती है, वेरिएबल नाम या TypeScript प्रकार से नहीं।

समीक्षित रेंडरिंग सीमा से ठीक पहले सैनिटाइज करें। राइट-टाइम सैनिटाइजेशन एक अतिरिक्त जाँच प्रदान कर सकता है, लेकिन केवल इस पर भरोसा करने से पुरानी पंक्तियों, आयातों, माइग्रेशन, वैकल्पिक API और नीति परिवर्तनों के लिए अंतराल रह जाता है। यदि सिस्टम प्रदर्शन के लिए सैनिटाइज किए गए आउटपुट को संग्रहीत करता है, तो सैनिटाइज़र और नीति संस्करण को रिकॉर्ड करें ताकि सुरक्षा अपडेट के बाद पुरानी सामग्री को पुनः संसाधित किया जा सके।

सैनिटाइजेशन के बाद स्ट्रिंग संयोजन के साथ HTML को संशोधित न करें। सैनिटाइज की गई स्ट्रिंग को संपादित करके एक लिंक, हाइलाइट या रैपर जोड़ना एक असुरक्षित संरचना को फिर से पेश कर सकता है। अपरिष्कृत HTML क्षेत्र के बाहर विश्वसनीय UI बनाएं, या अंतिम सामग्री को फिर से सैनिटाइज़र के माध्यम से पास करें।

चरण 4: URL को संरचित इनपुट के रूप में मानें

HTML सैनिटाइजेशन में लिंक विशेषताओं को शामिल किया जाना चाहिए, लेकिन उत्पाद नीति भी स्पष्ट होनी चाहिए। एक उम्मीदवार URL को एक ज्ञात आधार के विरुद्ध पार्स करें, परिणामी प्रोटोकॉल का निरीक्षण करें, और केवल उन प्रोटोकॉल को स्वीकार करें जिनकी सुविधा को आवश्यकता है। इस परिदृश्य में, केवल HTTPS ही बचता है।

एक खतरनाक URL को एन्कोड करना इसकी स्कीम को स्वीकार्य नहीं बनाता है। href के लिए एक मान सही ढंग से एन्कोड किया जा सकता है और फिर भी स्क्रिप्ट-युक्त प्रोटोकॉल का उपयोग कर सकता है। URL निर्णय और HTML-विशेषता संदर्भ अलग-अलग जाँच हैं। एक नए टैब में खोले गए बाहरी लिंक के लिए, रेंडरर के माध्यम से उपयुक्त संबंध विशेषताएँ जोड़ें; यह ओपनर पहुँच को सीमित करता है लेकिन XSS रोकथाम को प्रतिस्थापित नहीं करता है।

उपयोगकर्ता-नियंत्रित स्क्रिप्ट URL से पूरी तरह बचें। eval, Function, स्ट्रिंग-आधारित setTimeout, स्ट्रिंग-आधारित setInterval, और गतिशील स्क्रिप्ट स्रोत निर्माण को अविश्वसनीय मान प्राप्त नहीं होने चाहिए। इन पाथों को हटाने या एक छोटे पूर्वनिर्धारित मैपिंग की आवश्यकता होती है, न कि एक सामान्य-उद्देश्य सैनिटाइज़र की।

चरण 5: रक्षा की दूसरी पंक्ति के रूप में CSP जोड़ें

यदि कोई सिंक छूट जाता है तो एक CSP स्क्रिप्ट निष्पादन को प्रतिबंधित कर सकता है। एक प्रतिक्रिया हेडर को प्राथमिकता दें और एप्लिकेशन के वास्तविक संसाधनों के आधार पर एक नीति डिज़ाइन करें। एक सरलीकृत दिशा है:

http
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{per-response-random-value}';
  object-src 'none';
  base-uri 'none'

नॉन (nonce) अप्रत्याशित और प्रति प्रतिक्रिया अद्वितीय होना चाहिए, और केवल अनुमोदित स्क्रिप्ट ही इसे प्राप्त करती हैं। एक हैश-आधारित नीति स्थिर इनलाइन सामग्री के अनुकूल हो सकती है। केवल उल्लंघनों को शांत करने के लिए विस्तृत होस्ट सूचियों या unsafe-inline के साथ नीति को कमजोर करने से बचें।

Content-Security-Policy-Report-Only से शुरुआत करें, उल्लंघन एकत्र करें, अप्रत्याशित इनलाइन कोड हटाएं, और फिर लागू करें। रिपोर्ट-ओनली मोड परिनियोजन साक्ष्य प्रदान करता है लेकिन कुछ भी ब्लॉक नहीं करता है। CSP डिफेंस-इन-डेप्थ बना रहता है: अनुमत स्क्रिप्ट में अभी भी पृष्ठ के विशेषाधिकार होते हैं, ब्राउज़र समर्थन सुविधा के अनुसार भिन्न होता है, और एक अनुमेय नीति मूल शोषण को काम करता हुआ छोड़ सकती है।

चरण 6: DOM इंजेक्शन को नियंत्रित करने के लिए Trusted Types का उपयोग करें

जहाँ समर्थित हो, वहां CSP निर्देश जोड़ें:

http
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-rich-text

प्रवर्तन कवर किए गए DOM इंजेक्शन सिंक को सामान्य स्ट्रिंग्स को अस्वीकार करने के लिए मजबूर करता है। एप्लिकेशन केवल नामित नीति बनाता है, और वह नीति अनुमोदित सैनिटाइज़र को HTML निर्माण सौंपती है। यह एक मूक असुरक्षित असाइनमेंट को एक दृश्यमान अपवाद में बदल देता है और परीक्षणों और निगरानी में नए रॉ-स्ट्रिंग सिंक को पकड़ना आसान बनाता है।

एक नीति जो इनपुट को अपरिवर्तित लौटाती है, नियंत्रण को विफल कर देती है। एक व्यापक डिफ़ॉल्ट नीति स्वचालित रूप से प्रत्येक स्ट्रिंग को परिवर्तित करके लीगेसी पाथ को भी छिपा सकती है। डायग्नोस्टिक्स के लिए माइग्रेशन के दौरान अस्थायी रूप से एक डिफ़ॉल्ट नीति का उपयोग करें, फिर कॉलर्स को स्पष्ट विश्वसनीय मानों पर ले जाएं और परिहार्य सिंक को हटा दें।

Trusted Types कोड निष्पादित करने के हर संभव तरीके को कवर नहीं करता है, और पुराने ब्राउज़रों में प्रवर्तन की कमी हो सकती है। आधार रेखा सुरक्षित रेंडरिंग, संकीर्ण सैनिटाइजेशन, URL सत्यापन और निष्पादन योग्य स्ट्रिंग API को हटाना बनी हुई है।

चरण 7: रेंडरिंग फ़ंक्शन के बाहर प्रभाव को कम करें

सत्र कुकीज़ को आम तौर पर HttpOnly, Secure और एक उपयुक्त SameSite नीति का उपयोग करना चाहिए। HttpOnly इंजेक्ट की गई JavaScript को सीधे उस कुकी को पढ़ने से रोक सकता है, लेकिन एक सक्रिय XSS अभी भी उपयोगकर्ता के रूप में अनुरोध भेज सकता है या पृष्ठ पर उपलब्ध डेटा पढ़ सकता है। कुकी विशेषताएँ प्रभाव को कम करती हैं; वे इंजेक्शन पाथ को बंद नहीं करती हैं।

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

चरण 8: सुरक्षा और इच्छित फ़ॉर्मेटिंग दोनों को सत्यापित करें

एक परीक्षण कॉर्पस बनाएं जो विभिन्न पार्सर पाथ को कवर करता है:

text
<img src=x onerror=alert(1)>
<a href="javascript:alert(1)">open</a>
<svg onload=alert(1)></svg>
"><script>alert(1)</script>
malformed tags and mixed character encodings

वास्तविक विनाशकारी व्यवहार के बजाय एक पृथक परीक्षण वातावरण में निष्क्रिय (inert) परीक्षण कॉलबैक का उपयोग करें। सत्यापित करें:

  1. सादी टिप्पणियाँ प्रत्येक वर्ण को प्रदर्शित करती हैं और कोई तत्व नहीं बनाती हैं।
  2. खोज पैरामीटर सामान्य नेविगेशन, एन्कोडेड URL, ब्राउज़र इतिहास और हाइड्रेशन के बाद टेक्स्ट बने रहते हैं।
  3. अनुमत घोषणा टैग बच जाते हैं जबकि स्क्रिप्ट, इवेंट हैंडलर, शैलियाँ, SVG, फ़्रेम और असुरक्षित URL

हटा दिए जाते हैं।

  1. सैनिटाइज़र आउटपुट को अपरिष्कृत HTML सिंक तक पहुँचने से पहले रूपांतरित (mutate) नहीं किया जाता है।
  2. CSP रिपोर्ट-ओनली टेलीमेट्री को समझा जाता है, फिर प्रवर्तन जानबूझकर पेश किए गए परीक्षण सिंक को ब्लॉक करता है।
  3. Trusted Types प्रवर्तन एक रॉ स्ट्रिंग पर थ्रो करता है और केवल अनुमोदित सैनिटाइज की गई नीति आउटपुट को स्वीकार करता है।
  4. मौजूदा रिच-टेक्स्ट फिक्स्चर, लिंक, स्क्रीन-रीडर संरचना और कॉपी-पेस्ट व्यवहार अभी भी काम करते हैं।

नए सिंक के लिए स्थिर समीक्षा, सैनिटाइज़र नीति के लिए यूनिट परीक्षण, प्रत्येक रेंडरिंग पाथ के लिए एकीकरण परीक्षण, और समर्थित मैट्रिक्स के विरुद्ध ब्राउज़र परीक्षण जोड़ें। सैनिटाइज़र को पैच रखें और ब्राउज़र, फ्रेमवर्क, सैनिटाइज़र, एडिटर या नीति बदलने पर शत्रुतापूर्ण कॉर्पस को फिर से चलाएं।

उच्च-गुणवत्ता वाला नमूना उत्तर

"मैं पहले अविश्वसनीय स्रोतों और उन्हें पार्स करने वाले ब्राउज़र API की पहचान करूँगा। डेटाबेस टिप्पणी मुख्य भाग, घोषणा HTML, और location.search से q स्रोत हैं। innerHTML, dangerouslySetInnerHTML, और कोई भी स्क्रिप्ट या स्क्रिप्ट-URL कंस्ट्रक्टर वे सिंक हैं जिन्हें मैं ट्रेस करूँगा।

टिप्पणियाँ और खोज बैनर टेक्स्ट सुविधाएँ हैं। मैं उन्हें React चिल्ड्रन के रूप में रेंडर करूँगा या textContent असाइन करूँगा, ताकि ब्राउज़र कभी भी उनके वर्णों को मार्कअप के रूप में व्याख्यायित न करे। घोषणा का एक अलग अनुबंध है क्योंकि यह सीमित HTML की अनुमति देता है। मैं पैराग्राफ, एम्फैसिस, सूचियों और HTTPS लिंक के लिए एक छोटी अनुमति-सूची परिभाषित करूँगा, अंतिम मान को एक अनुरक्षित पार्सर-आधारित सैनिटाइज़र के माध्यम से पास करूँगा, और एक समीक्षित अपरिष्कृत HTML घटक रखूँगा। सैनिटाइज़र इवेंट हैंडलर, शैलियों, SVG, फ़्रेम और असुरक्षित URL स्कीमों को भी हटा देगा। उस चरण के बाद कोई भी कोड मार्कअप को संयोजित नहीं करेगा।

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

डिफेंस-इन-डेप्थ के लिए, मैं रिपोर्ट-ओनली मोड के माध्यम से एक नॉन- या हैश-आधारित CSP रोल आउट करूँगा, उल्लंघनों को हटाऊंगा, फिर इसे लागू करूँगा। जहाँ हमारा ब्राउज़र समर्थन इसकी अनुमति देता है, मैं स्क्रिप्ट सिंक के लिए Trusted Types की आवश्यकता रखूँगा और केवल एक नामित नीति की अनुमति दूंगा जो अनुमोदित सैनिटाइज़र को कॉल करती है। मैं CSP, HttpOnly कुकीज़, या प्राथमिक सुधार के रूप में इनपुट को अपरिवर्तित लौटाने वाली Trusted Types नीति का उपयोग नहीं करूँगा।

मेरे सत्यापन में स्टोर्ड पेलोड, URL पेलोड, विकृत मार्कअप, इवेंट विशेषताएँ, SVG और स्क्रिप्ट URL शामिल होंगे। मैं दावा करूँगा कि टेक्स्ट पाथ कोई तत्व नहीं बनाते हैं, अनुमत फ़ॉर्मेटिंग बची रहती है, अस्वीकृत सामग्री हटा दी जाती है, Trusted Types के तहत रॉ स्ट्रिंग असाइनमेंट विफल हो जाते हैं, और लागू किया गया CSP जानबूझकर पेश किए गए परीक्षण सिंक को ब्लॉक करता है। मैं सैनिटाइज़र को अपडेट भी रखूँगा और नए इंजेक्शन सिंक को एक कोड-समीक्षा और स्थिर-विश्लेषण चेकपॉइंट बनाऊंगा।"

सामान्य गलतियाँ

  • प्रत्येक मान को उसी तरह से एस्केप करना → ब्राउज़र विभिन्न नियमों के तहत HTML, विशेषताओं, URL, CSS और JavaScript को पार्स करते हैं → डेटा को निष्पादन योग्य संदर्भों से बाहर रखें और सटीक सिंक द्वारा आवश्यक सुरक्षा लागू करें।
  • स्क्रिप्ट टैग हटाने के बाद सादे टेक्स्ट को innerHTML के माध्यम से भेजना → इवेंट विशेषताएँ, विकृत मार्कअप, SVG, URL स्कीमें और पार्सर व्यवहार बने रहते हैं → सिंक को JSX टेक्स्ट रेंडरिंग या textContent से बदलें।
  • रिच टेक्स्ट को एन्कोड करना → मार्कअप शाब्दिक रूप से दिखाई देता है और सुविधा टूट जाती है → जब HTML एक स्पष्ट उत्पाद आवश्यकता हो तो एक संकीर्ण अनुमति-सूची के साथ एक अनुरक्षित HTML सैनिटाइज़र का उपयोग करें।
  • केवल-मॉडरेटर सामग्री पर भरोसा करना → समझौता किए गए खाते, आयात, माइग्रेशन और API दोष शत्रुतापूर्ण मार्कअप को बनाए रख सकते हैं → रेंडरिंग सीमा पर संग्रहीत सामग्री को अविश्वसनीय मानें।
  • सैनिटाइज करना और फिर अधिक HTML जोड़ना → बाद का परिवर्तन एक निष्पादन योग्य निर्माण को फिर से बना सकता है → समीक्षित सिंक से पहले सैनिटाइजेशन को अंतिम परिवर्तन बनाएं।
  • केवल HTML एन्कोडिंग द्वारा href को मान्य करना → एक एन्कोड किया गया मान अभी भी एक अस्वीकार्य प्रोटोकॉल ले जा सकता है → URL को पार्स करें और केवल आवश्यक स्कीमों और गंतव्यों की अनुमति दें।
  • React ऑटो-एस्केपिंग को सार्वभौमिक मानना → एस्केप हैच और प्रत्यक्ष DOM API सामान्य स्ट्रिंग इंटरपोलेशन को बायपास करते हैं → प्रत्येक अपरिष्कृत HTML और निष्पादन योग्य स्ट्रिंग पाथ की सूची बनाएं।
  • केवल CSP पर निर्भर रहना → कमजोर नीतियां, अनुमत स्क्रिप्ट या असमर्थित सुविधाएं सिंक को शोषण योग्य छोड़ सकती हैं → पहले असुरक्षित सिंक हटाएं और एक अतिरिक्त बाधा के रूप में CSP का उपयोग करें।
  • एक Trusted Types नीति बनाना जो अपने इनपुट को लौटाती है → ब्राउज़र एक विश्वसनीय परिवर्तन के बिना एक विश्वसनीय ऑब्जेक्ट देखता है → नीति नामों को प्रतिबंधित करें और समीक्षित सैनिटाइज़र को सौंपें।
  • केवल यह जाँचना कि अलर्ट पेलोड बंद हो गया है → एक पेलोड URL स्कीमों, विकृत मार्कअप, वैकल्पिक तत्वों, या अनुमत फ़ॉर्मेटिंग में रिग्रेशन को कवर नहीं करता है → एक विविध शत्रुतापूर्ण कॉर्पस और सकारात्मक रिच-टेक्स्ट फिक्स्चर बनाए रखें।

अनुवर्ती प्रश्न

अनुवर्ती 1: आप सैकड़ों innerHTML असाइनमेंट वाले एक लीगेसी एप्लिकेशन को कैसे माइग्रेट करेंगे?

सिंक की सूची बनाएं और उन्हें पहुँच योग्य अविश्वसनीय स्रोतों, उपयोगकर्ता जोखिम और विशेषाधिकार द्वारा रैंक करें। पहले केवल-टेक्स्ट पाथ को बदलें। शेष वैध HTML के लिए एक समीक्षित रिच-टेक्स्ट सीमा पेश करें। रनटाइम पाथ को प्रकट करने के लिए रिपोर्ट-ओनली या डायग्नोस्टिक मोड में CSP और Trusted Types को तैनात करें जिन्हें स्थिर खोज मिस कर देती है। एक अस्थायी डिफ़ॉल्ट Trusted Types नीति लीगेसी कॉल को लॉग कर सकती है, लेकिन इसे अपरिवर्तित स्ट्रिंग्स को चुपचाप स्वीकृत नहीं करना चाहिए; कॉलर्स को स्पष्ट नीतियों पर माइग्रेट करें और अस्थायी संगतता पाथ को हटा दें।

अनुवर्ती 2: यदि घोषणाओं में छवियों और एम्बेडेड वीडियो की अनुमति होनी चाहिए तो क्या बदलता है?

विश्वास अनुबंध का विस्तार होता है। अनुमत छवि मूल (origins), URL स्कीमें, आयाम, लोडिंग व्यवहार और गोपनीयता नियमों को परिभाषित करें। छवियों को प्रॉक्सी करना प्रत्यक्ष तृतीय-पक्ष अनुरोधों को कम कर सकता है। एम्बेडेड वीडियो को एक छोटी प्रदाता अनुमति-सूची और केवल आवश्यक क्षमताओं वाले एक सैंडबॉक्स किए गए फ़्रेम का उपयोग करना चाहिए। सैनिटाइज़र नीति, CSP निर्देश, सहमति व्यवहार और परीक्षण कॉर्पस सभी बदलते हैं। मनमाने फ़्रेम, शैलियाँ और प्रदाता HTML को मौजूदा घोषणा रेंडरर में प्रवेश नहीं करना चाहिए।

अनुवर्ती 3: क्या होगा यदि एक सख्त CSP एनालिटिक्स और टैग-मैनेजर स्क्रिप्ट को तोड़ देता है?

प्रस्तावित नीति को रिपोर्ट-ओनली मोड में चलाएं और व्यावसायिक स्वामी और स्क्रिप्ट उद्देश्य के अनुसार प्रत्येक उल्लंघन को वर्गीकृत करें। अप्रयुक्त स्क्रिप्ट हटाएं, इनलाइन स्निपेट्स को अनुमोदित बाहरी मॉड्यूल से बदलें, और आवश्यकतानुसार स्क्रिप्ट को प्रति-प्रतिक्रिया नॉन या स्थिर हैश दें। एक विस्तृत वाइल्डकार्ड या unsafe-inline अधिकांश सुरक्षा सीमा को छोड़कर संगतता को पुनर्स्थापित करता है। यदि कोई टैग प्रबंधक मनमानी स्क्रिप्ट इंजेक्ट कर सकता है, तो दस्तावेज़ करें कि यह एक विशेषाधिकार प्राप्त कोड पाथ बना हुआ है और प्रतिबंधित करें कि इसके माध्यम से कौन प्रकाशित कर सकता है।

अनुवर्ती 4: सर्वर पहले से ही घोषणाओं को सैनिटाइज करता है। फ्रंटएंड सीमा क्यों रखें?

अपरिष्कृत HTML घटक को एक सत्यापन योग्य इनपुट अनुबंध की आवश्यकता होती है, चाहे परिवर्तन कहीं भी चलता हो। वैकल्पिक API, पुरानी पंक्तियाँ, आयात, कैश प्रविष्टियाँ, माइग्रेशन, या एक बदली हुई नीति राइट-टाइम धारणा को बायपास कर सकती है। सिंक को एनकैप्सुलेट करें ताकि कॉलर्स केवल वर्तमान सैनिटाइज़र से आउटपुट प्रदान कर सकें, उस अनुबंध का परीक्षण करें, और संग्रहीत सैनिटाइज की गई सामग्री को वर्शन करें यदि इसका पुन: उपयोग किया जाता है। सर्वर जाँच सिस्टम में प्रवेश करने वाले खराब डेटा को कम करती है; रेंडरिंग सीमा एक असत्यापित मान को पार्सर तक पहुँचने से रोकती है।

अनुवर्ती 5: आप एक प्रोडक्शन XSS रिपोर्ट की जांच कैसे करेंगे?

एक सामान्य खाते में पेलोड को निष्पादित किए बिना रिपोर्ट किए गए URL, सामग्री पहचानकर्ता, ब्राउज़र, CSP रिपोर्ट और प्रासंगिक परिनियोजन संस्करण को सुरक्षित रखें। एक अलग वातावरण में पुनरुत्पादन करें, सटीक सोर्स-टू-सिंक पाथ को ट्रेस करें, और निर्धारित करें कि पेलोड संग्रहीत था, अनुरोध-संचालित था, या किसी तीसरे पक्ष द्वारा आपूर्ति की गई थी। कमजोर रेंडरिंग पाथ को हटाएं या अक्षम करें, जहाँ आवश्यक हो दुर्भावनापूर्ण संग्रहीत सामग्री को अमान्य करें, उजागर क्रेडेंशियल्स को घुमाएं (rotate करें), एक्सपोज़र विंडो के दौरान की गई संवेदनशील कार्रवाइयों की समीक्षा करें, फिर सुविधा को पुनर्स्थापित करने से पहले रिग्रेशन कॉर्पस में पेलोड क्लास जोड़ें।

सार्वजनिक स्रोत

संबंधित प्रश्न