वेब डेवलपर के लिए साइट आइसोलेशन

डेस्कटॉप पर Chrome 67 में एक नई सुविधा है, जिसे साइट आइसोलेशन कहा जाता है. यह सुविधा डिफ़ॉल्ट रूप से चालू होती है. इस लेख में बताया गया है कि साइट आइसोलेशन क्या है, यह क्यों ज़रूरी है, और वेब डेवलपर को इसकी जानकारी क्यों होनी चाहिए.

साइट आइसोलेशन क्या है?

इंटरनेट का इस्तेमाल, बिल्ली के वीडियो देखने और क्रिप्टो करंसी वॉलेट मैनेज करने के साथ-साथ कई अन्य कामों के लिए किया जाता है. हालांकि, आपके पास यह तय करने का विकल्प होता है कि fluffycats.example को आपके कीमती क्रिप्टो करंसी का ऐक्सेस मिले या नहीं! आम तौर पर, एक ही सोर्स वाली नीति की वजह से, वेबसाइटें ब्राउज़र में एक-दूसरे का डेटा ऐक्सेस नहीं कर सकतीं. हालांकि, नुकसान पहुंचाने वाली वेबसाइटें, दूसरी वेबसाइटों पर हमला करने के लिए इस नीति को बायपास करने की कोशिश कर सकती हैं. साथ ही, कभी-कभी एक ही सोर्स की नीति लागू करने वाले ब्राउज़र कोड में सुरक्षा से जुड़े गड़बड़ियां भी मिलती हैं. Chrome टीम, इस तरह के गड़बड़ियों को जल्द से जल्द ठीक करने की कोशिश करती है.

साइट आइसोलेशन, Chrome की सुरक्षा से जुड़ी एक सुविधा है. इससे, आपके डिवाइस पर इस तरह के अटैक होने की संभावना कम हो जाती है. यह पक्का करता है कि अलग-अलग वेबसाइटों के पेजों को हमेशा अलग-अलग प्रोसेस में रखा जाए. हर प्रोसेस, सैंडबॉक्स में चलती है, जो प्रोसेस को सीमित करती है. यह प्रोसेस, अन्य साइटों से कुछ खास तरह का संवेदनशील डेटा पाने से भी रोकती है. इस वजह से, साइट अलग-अलग प्रोसेस में होने की वजह से, नुकसान पहुंचाने वाली वेबसाइट के लिए, अन्य साइटों से डेटा चुराने के लिए, Spectre जैसे स्पेक्ट्रल साइड-चैनल अटैक का इस्तेमाल करना बहुत मुश्किल हो जाता है. Chrome की टीम, नीति उल्लंघन ठीक करने के लिए ज़रूरी कार्रवाई पूरी करने के बाद, साइट अलग करने की सुविधा का इस्तेमाल करेगी. इससे, हमलावर के पेज के अपने प्रोसेस में कुछ नियमों का उल्लंघन करने पर भी मदद मिलेगी.

साइट अलगाव की सुविधा से, भरोसेमंद वेबसाइटों के लिए, अन्य वेबसाइटों पर मौजूद आपके खातों से जानकारी ऐक्सेस करना या उसे चुराना मुश्किल हो जाता है. यह अलग-अलग तरह के सुरक्षा बग से अतिरिक्त सुरक्षा देता है. जैसे, हाल ही में हुए Meltdown और Spectre साइड-चैनल हमले.

साइट आइसोलेशन के बारे में ज़्यादा जानने के लिए, Google के सुरक्षा ब्लॉग पर हमारा लेख पढ़ें.

क्रॉस-ऑरिजिन रीड ब्लॉकिंग

सभी क्रॉस-साइट पेजों को अलग-अलग प्रोसेस में डालने के बाद भी, पेज कुछ क्रॉस-साइट सब-रिसॉर्स का अनुरोध कर सकते हैं. जैसे, इमेज और JavaScript. कोई नुकसान पहुंचाने वाला वेब पेज, संवेदनशील डेटा वाली JSON फ़ाइल को लोड करने के लिए, <img> एलिमेंट का इस्तेमाल कर सकता है. जैसे, आपके बैंक बैलेंस की जानकारी:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

साइट अलगाव के बिना, JSON फ़ाइल का कॉन्टेंट रेंडरर प्रोसेस की मेमोरी में चला जाएगा. इस दौरान, रेंडरर को पता चलता है कि यह मान्य इमेज फ़ॉर्मैट नहीं है और वह इमेज को रेंडर नहीं करता. हालांकि, हमलावर उस मेमोरी का इस्तेमाल करने के लिए, Spectre जैसी किसी कमजोरी का फ़ायदा उठा सकता है.

<img> के बजाय, हमलावर संवेदनशील डेटा को मेमोरी में डालने के लिए <script> का इस्तेमाल भी कर सकता है:

<script src="https://your-bank.example/balance.json"></script>

क्रॉस-ओरिजिन रीड ब्लॉकिंग या सीओआरबी, सुरक्षा से जुड़ी एक नई सुविधा है. यह balance.json के कॉन्टेंट को, MIME टाइप के आधार पर रेंडरर प्रोसेस मेमोरी में कभी भी शामिल होने से रोकती है.

आइए, जानते हैं कि सीओआरबी कैसे काम करता है. कोई वेबसाइट, सर्वर से दो तरह के संसाधनों का अनुरोध कर सकती है:

  1. डेटा रिसॉर्स, जैसे कि एचटीएमएल, एक्सएमएल या JSON दस्तावेज़
  2. मीडिया रिसॉर्स, जैसे कि इमेज, JavaScript, सीएसएस या फ़ॉन्ट

कोई वेबसाइट, अपने ओरिजिन या दूसरे ओरिजिन से डेटा रिसॉर्स पा सकती है. इसके लिए, Access-Control-Allow-Origin: * जैसे अनुमति देने वाले CORS हेडर की ज़रूरत होती है. दूसरी ओर, मीडिया रिसॉर्स को किसी भी ऑरिजिन से शामिल किया जा सकता है. इसके लिए, अनुमति देने वाले सीओआरएस हेडर की ज़रूरत नहीं होती.

CORB, रेंडरर प्रोसेस को क्रॉस-ऑरिजिन डेटा रिसॉर्स (जैसे, एचटीएमएल, एक्सएमएल या JSON) पाने से रोकता है, अगर:

  • रिसॉर्स में X-Content-Type-Options: nosniff हेडर है
  • सीओआरएस, संसाधन को ऐक्सेस करने की अनुमति साफ़ तौर पर नहीं देता

अगर क्रॉस-ऑरिजिन डेटा रिसॉर्स में X-Content-Type-Options: nosniff हेडर सेट नहीं है, तो CORB, रिस्पॉन्स बॉडी को स्निफ करके यह पता लगाने की कोशिश करता है कि वह एचटीएमएल, एक्सएमएल या JSON है. ऐसा करना ज़रूरी है, क्योंकि कुछ वेब सर्वर गलत तरीके से कॉन्फ़िगर किए गए हैं और वे इमेज को text/html के तौर पर दिखाते हैं.

सीओआरबी नीति के तहत ब्लॉक किए गए डेटा रिसॉर्स, प्रोसेस में खाली के तौर पर दिखाए जाते हैं. हालांकि, अनुरोध अब भी बैकग्राउंड में होता है. इस वजह से, नुकसान पहुंचाने वाले वेब पेज को, डेटा चुराने के लिए क्रॉस-साइट डेटा को अपनी प्रोसेस में शामिल करने में मुश्किल होती है.

बेहतर सुरक्षा और सीओआरबी का फ़ायदा पाने के लिए, हमारा सुझाव है कि आप ये काम करें:

  • जवाबों को सही Content-Type हेडर के साथ मार्क करें. (उदाहरण के लिए, एचटीएमएल रिसॉर्स को text/html के तौर पर, JSON रिसॉर्स को JSON MIME टाइप के साथ, और एक्सएमएल रिसॉर्स को एक्सएमएल MIME टाइप के साथ दिखाया जाना चाहिए).
  • X-Content-Type-Options: nosniff हेडर का इस्तेमाल करके, स्निफ़िंग से ऑप्ट आउट करें. इस हेडर के बिना, Chrome कॉन्टेंट का तुरंत विश्लेषण करता है, ताकि यह पक्का किया जा सके कि टाइप सही है. हालांकि, यह JavaScript फ़ाइलों जैसी चीज़ों को ब्लॉक करने से बचने के लिए, जवाबों को अनुमति देता है. इसलिए, बेहतर होगा कि आप खुद ही सही तरीके से जवाब दें.

ज़्यादा जानकारी के लिए, वेब डेवलपर के लिए सीओआरबी लेख या सीओआरबी के बारे में ज़्यादा जानकारी देने वाला हमारा एक्सप्लेनर पढ़ें.

वेब डेवलपर को साइट आइसोलेशन की क्यों ज़रूरत है?

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

हालांकि, इस नियम के कुछ अपवाद हैं. साइट आइसोलेशन की सुविधा चालू करने पर, कुछ साइड इफ़ेक्ट होते हैं. इनसे आपकी वेबसाइट पर असर पड़ सकता है. हम साइट अलगाव से जुड़ी समस्याओं की सूची रखते हैं. साथ ही, यहां सबसे ज़रूरी समस्याओं के बारे में बताया गया है.

पूरे पेज का लेआउट अब सिंक नहीं होता

साइट अलगाव की सुविधा के साथ, अब पूरे पेज के लेआउट के सिंक होने की गारंटी नहीं है. ऐसा इसलिए है, क्योंकि अब किसी पेज के फ़्रेम कई प्रोसेस में हो सकते हैं. अगर पेज यह मानते हैं कि लेआउट में हुए बदलाव, पेज के सभी फ़्रेम पर तुरंत लागू हो जाते हैं, तो उन पर इसका असर पड़ सकता है.

उदाहरण के लिए, fluffykittens.example नाम की एक वेबसाइट को लें, जो social-widget.example पर होस्ट किए गए सोशल विजेट से इंटरैक्ट करती है:

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

शुरुआत में, सोशल विजेट के <iframe> की चौड़ाई 123 पिक्सल होती है. हालांकि, इसके बाद FluffyKittens पेज, चौड़ाई को 456 पिक्सल (लेआउट को ट्रिगर करना) में बदल देता है और सोशल विजेट को एक मैसेज भेजता है. इस विजेट में यह कोड होता है:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

जब भी सोशल विजेट को postMessage एपीआई से कोई मैसेज मिलता है, तो वह अपने रूट <html> एलिमेंट की चौड़ाई को लॉग करता है.

चौड़ाई की कौनसी वैल्यू लॉग की जाती है? Chrome पर साइट अलगाव की सुविधा चालू होने से पहले, इसका जवाब 456 था. document.documentElement.clientWidth को ऐक्सेस करने पर, लेआउट को फ़ोर्स किया जाता है. Chrome पर साइट आइसोलेशन की सुविधा चालू होने से पहले, यह सिंक होता था. हालांकि, साइट आइसोलेशन की सुविधा चालू होने पर, क्रॉस-ऑरिजिन सोशल विजेट का फिर से लेआउट, अब अलग प्रोसेस में असिंक्रोनस तरीके से होता है. इसलिए, जवाब अब 123 भी हो सकता है. इसका मतलब है कि width की पुरानी वैल्यू.

अगर कोई पेज, क्रॉस-ऑरिजिन <iframe> का साइज़ बदलता है और फिर उसमें postMessage भेजता है, तो हो सकता है कि साइट अलगाव की सुविधा के साथ, मैसेज पाने वाले फ़्रेम को मैसेज मिलने के समय उसका नया साइज़ न पता हो. आम तौर पर, अगर पेज यह मानते हैं कि लेआउट में किया गया बदलाव, पेज के सभी फ़्रेम में तुरंत लागू हो जाता है, तो हो सकता है कि पेज काम न करें.

इस खास उदाहरण में, ज़्यादा बेहतर समाधान के लिए पैरंट फ़्रेम में width सेट किया जाएगा. साथ ही, resize इवेंट को सुनकर <iframe> में हुए बदलाव का पता लगाया जाएगा.

अनलोड हैंडलर के टाइम आउट होने की संभावना ज़्यादा हो सकती है

जब कोई फ़्रेम नेविगेट करता है या बंद होता है, तो पुराने दस्तावेज़ के साथ-साथ उसमें एम्बेड किए गए सभी सबफ़्रेम दस्तावेज़, अपना unload हैंडलर चलाते हैं. अगर नया नेविगेशन, एक ही रेंडरर प्रोसेस में होता है (उदाहरण के लिए, एक ही ऑरिजिन वाले नेविगेशन के लिए), तो नए नेविगेशन को कमिट करने से पहले, पुराने दस्तावेज़ और उसके सबफ़्रेम के unload हैंडलर, मनमुताबिक लंबे समय तक चल सकते हैं.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

इस स्थिति में, सभी फ़्रेम में unload हैंडलर काफ़ी भरोसेमंद होते हैं.

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

साइट आइसोलेशन की सुविधा चालू होने पर, एक साइट से दूसरी साइट पर जाने की सभी प्रोसेस, अलग-अलग हो जाती हैं. इससे अलग-अलग साइटों के दस्तावेज़, एक-दूसरे के साथ प्रोसेस शेयर नहीं करते. इस वजह से, ऊपर बताई गई स्थिति ज़्यादा मामलों में लागू होती है. साथ ही, <iframe> में मौजूद अनलोड हैंडलर में अक्सर बैकग्राउंड और टाइम आउट के व्यवहार, ऊपर बताए गए होते हैं.

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

साइट अलगाव की सुविधा चालू करने के ये बुनियादी नतीजे हैं. Chrome की टीम, सामान्य इस्तेमाल के उदाहरणों के लिए, अनलोड हैंडलर की भरोसेमंदता को बेहतर बनाने पर काम कर रही है. हालांकि, ऐसा सिर्फ़ तब किया जाएगा, जब यह मुमकिन हो. हम उन गड़बड़ियों के बारे में भी जानते हैं जिनमें सबफ़्रेम अनलोड हैंडलर, अब तक कुछ सुविधाओं का इस्तेमाल नहीं कर पा रहे हैं. हम इन गड़बड़ियों को ठीक करने के लिए काम कर रहे हैं.

अनलोड हैंडलर के लिए, सेशन खत्म होने पर पिंग भेजना एक अहम मामला है. आम तौर पर, ऐसा करने के लिए यह तरीका अपनाया जाता है:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

इस बदलाव के हिसाब से, navigator.sendBeacon का इस्तेमाल करना बेहतर तरीका है:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

अगर आपको अनुरोध पर ज़्यादा कंट्रोल चाहिए, तो Fetch API के keepalive विकल्प का इस्तेमाल किया जा सकता है:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

नतीजा

साइट आइसोलेशन की सुविधा से, हर साइट को अलग प्रोसेस में अलग रखा जाता है. इससे, भरोसेमंद नहीं होने वाली वेबसाइटों के लिए, दूसरी वेबसाइटों पर मौजूद आपके खातों से जानकारी ऐक्सेस करना या उसे चुराना मुश्किल हो जाता है. इसके तहत, सीओआरबी, संवेदनशील डेटा संसाधनों को रेंडरर प्रोसेस से बाहर रखने की कोशिश करता है. ऊपर दिए गए सुझावों से, आपको सुरक्षा से जुड़ी इन नई सुविधाओं का ज़्यादा से ज़्यादा फ़ायदा पाने में मदद मिलेगी.

इस लेख के ड्राफ़्ट को पढ़ने और अपने सुझाव देने के लिए, Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhie Panicker, और Thomas Steiner को धन्यवाद.