सीएसआरएफ़, एक्सएसएसआई, और क्रॉस-ऑरिजिन जानकारी लीक होने से रोकें.
आपको अपने वेब संसाधनों को अलग रखने की ज़रूरत क्यों है?
कई वेब ऐप्लिकेशन पर क्रॉस-ओरिजिन हमले हो सकते हैं. जैसे, किसी दूसरी साइट से किए जाने वाले फ़र्ज़ी अनुरोध (सीएसआरएफ़), किसी दूसरी साइट की स्क्रिप्ट को शामिल करना (XSSI), टाइमिंग हमले, क्रॉस-ओरिजिन जानकारी लीक होना या अनुमानित तरीके से एक्सीक्यूशन साइड-चैनल (Spectre) हमले.
मेटाडेटा फ़ेच करें अनुरोध हेडर, आपको इन सामान्य क्रॉस-ऑरिजिन हमलों से अपने ऐप्लिकेशन की सुरक्षा करने के लिए, मज़बूत सुरक्षा प्रणाली—संसाधन अलग करने की नीति—का इस्तेमाल करने की अनुमति देते हैं.
आम तौर पर, किसी वेब ऐप्लिकेशन से एक्सपोज़ किए गए रिसॉर्स को सिर्फ़ ऐप्लिकेशन ही लोड करता है, न कि दूसरी वेबसाइटें. ऐसे मामलों में, मेटाडेटा के अनुरोध के हेडर पर आधारित संसाधन अलग करने की नीति को लागू करने में कम मेहनत लगती है और साथ ही ऐप्लिकेशन को क्रॉस-साइट हमलों से भी सुरक्षित रखा जाता है.
ब्राउज़र के साथ काम करना
मेटाडेटा फ़ेच करने के लिए रिक्वेस्ट हेडर, सभी मॉडर्न ब्राउज़र इंजन के साथ काम करते हैं.
बैकग्राउंड
कई क्रॉस-साइट हमले हो सकते हैं, क्योंकि वेब डिफ़ॉल्ट रूप से खुला होता है और आपका ऐप्लिकेशन सर्वर, बाहरी ऐप्लिकेशन से होने वाले कम्यूनिकेशन से आसानी से खुद को सुरक्षित नहीं रख सकता. क्रॉस-ओरिजिन हमले का एक सामान्य उदाहरण, क्रॉस-साइट रिक्वेस्ट फ़ोरजरी (सीएसआरएफ़) है. इसमें हमलावर, उपयोगकर्ता को अपनी नियंत्रण वाली साइट पर लाकर, उस सर्वर पर फ़ॉर्म सबमिट करता है जिस पर उपयोगकर्ता ने लॉग इन किया हुआ है. सर्वर यह नहीं बता सकता कि अनुरोध किसी अन्य डोमेन (क्रॉस-साइट) से आया है या नहीं और ब्राउज़र अपने-आप क्रॉस-साइट अनुरोधों में कुकी को जोड़ देता है. इसलिए, सर्वर उपयोगकर्ता की ओर से हमलावर की ओर से अनुरोध की गई कार्रवाई को पूरा करेगा.
क्रॉस-साइट स्क्रिप्ट शामिल करने (XSSI) या क्रॉस-ऑरिजिन जानकारी लीक जैसे अन्य क्रॉस-साइट हमले, सीएसआरएफ की तरह ही होते हैं. साथ ही, ये हमलावरों के कंट्रोल वाले दस्तावेज़ में, पीड़ितों के ऐप्लिकेशन से मिलने वाले संसाधनों को लोड करने और पीड़ितों के आवेदन की जानकारी को लीक करने पर निर्भर करते हैं. ऐप्लिकेशन, भरोसेमंद अनुरोधों और अविश्वसनीय अनुरोधों में आसानी से अंतर नहीं कर सकते. इसलिए, वे नुकसान पहुंचाने वाले क्रॉस-साइट ट्रैफ़िक को खारिज नहीं कर सकते.
पेश है मेटाडेटा फ़ेच करने की सुविधा
मेटाडेटा अनुरोध हेडर फ़ेच करना, वेब प्लैटफ़ॉर्म की सुरक्षा से जुड़ी एक नई सुविधा है. इसे सर्वर को क्रॉस-ऑरिजिन हमलों से बचाने के लिए डिज़ाइन किया गया है. Sec-Fetch-*
हेडर के सेट में एचटीटीपी अनुरोध के कॉन्टेक्स्ट के बारे में जानकारी देकर, वे अनुरोध को प्रोसेस करने से पहले, जवाब देने वाले सर्वर को सुरक्षा नीतियां लागू करने की अनुमति देते हैं. इससे डेवलपर यह तय कर सकते हैं कि किसी अनुरोध को स्वीकार करना है या अस्वीकार करना है. यह फ़ैसला, अनुरोध करने के तरीके और उसके इस्तेमाल के संदर्भ के आधार पर लिया जाता है. इससे, सिर्फ़ अपने ऐप्लिकेशन से किए गए मान्य अनुरोधों का जवाब दिया जा सकता है.
Sec-Fetch-Site
Sec-Fetch-Site
से सर्वर को पता चलता है कि अनुरोध किस साइट से भेजा गया है. ब्राउज़र इस वैल्यू को इनमें से किसी एक पर सेट करता है:
same-origin
, अगर अनुरोध आपके ऐप्लिकेशन से किया गया है (जैसे,site.example
)same-site
, अगर अनुरोध आपकी साइट के किसी सबडोमेन से किया गया हो (जैसे,bar.site.example
)none
, अगर अनुरोध साफ़ तौर पर उपयोगकर्ता एजेंट के साथ उपयोगकर्ता के इंटरैक्शन की वजह से हुआ था (जैसे कि किसी बुकमार्क पर क्लिक करना)- अगर अनुरोध किसी दूसरी वेबसाइट (जैसे,
evil.example
) से भेजा गया है, तोcross-site
Sec-Fetch-Mode
Sec-Fetch-Mode
, अनुरोध के मोड के बारे में बताता है. यह जानकारी करीब-करीब अनुरोध के टाइप से मेल खाती है. इसकी मदद से, रिसॉर्स लोड और नेविगेशन के अनुरोधों में अंतर किया जा सकता है. उदाहरण के लिए, navigate
का डेस्टिनेशन, टॉप-लेवल नेविगेशन अनुरोध को दिखाता है, जबकि no-cors
, इमेज लोड करने जैसे संसाधन अनुरोधों को दिखाता है.
Sec-Fetch-Dest
Sec-Fetch-Dest
, अनुरोध के डेस्टिनेशन को दिखाता है. उदाहरण के लिए, अगर script
या img
टैग की वजह से ब्राउज़र ने किसी संसाधन का अनुरोध किया है.
क्रॉस-ऑरिजिन हमलों से बचने के लिए, फ़ेच मेटाडेटा का इस्तेमाल करने का तरीका
इन अनुरोध हेडर में दी गई अतिरिक्त जानकारी काफ़ी आसान है. हालांकि, अतिरिक्त कॉन्टेक्स्ट की मदद से, सर्वर-साइड पर बेहतर सुरक्षा लॉजिक बनाया जा सकता है. इसे संसाधन अलगाव नीति भी कहा जाता है. इसके लिए, आपको सिर्फ़ कुछ लाइनों का कोड लिखना होगा.
संसाधन को अलग रखने की नीति लागू करना
रिसॉर्स को अलग रखने की नीति से, बाहरी वेबसाइटों को आपके रिसॉर्स का अनुरोध करने से रोका जाता है. इस तरह के ट्रैफ़िक को ब्लॉक करने से, क्रॉस-साइट वेब की सामान्य कमजोरियों को कम किया जा सकता है. जैसे, सीएसआरएफ़, XSSI, टाइमिंग अटैक, और क्रॉस-ऑरिजिन की जानकारी लीक होना. इस नीति को आपके ऐप्लिकेशन के सभी एंडपॉइंट के लिए चालू किया जा सकता है. इससे आपके ऐप्लिकेशन से आने वाले सभी संसाधन अनुरोधों के साथ-साथ, डायरेक्ट नेविगेशन (एचटीटीपी GET
अनुरोध के ज़रिए) की अनुमति भी मिलेगी. ऐसे एंडपॉइंट जिन्हें क्रॉस-साइट कॉन्टेक्स्ट में लोड किया जाना है (उदाहरण के लिए, सीओआरएस का इस्तेमाल करके लोड किए गए एंडपॉइंट) को इस लॉजिक से ऑप्ट आउट किया जा सकता है.
पहला चरण: उन ब्राउज़र से अनुरोध स्वीकार करना जो मेटाडेटा फ़ेच नहीं करते
सभी ब्राउज़र, मेटाडेटा फ़ेच करने की सुविधा के साथ काम नहीं करते. इसलिए, आपको उन अनुरोधों को अनुमति देनी होगी जो Sec-Fetch-*
हेडर सेट नहीं करते. इसके लिए, sec-fetch-site
की मौजूदगी की जांच करें.
if not req['sec-fetch-site']:
return True # Allow this request
दूसरा चरण: एक ही साइट और ब्राउज़र से शुरू किए गए अनुरोधों को अनुमति देना
ऐसे अनुरोध स्वीकार किए जाएंगे जो क्रॉस-ऑरिजिन कॉन्टेक्स्ट (जैसे, evil.example
) से नहीं किए गए हों. खास तौर पर, ये ऐसे अनुरोध होते हैं जो:
- आपके ऐप्लिकेशन से शुरू किया गया हो. उदाहरण के लिए, एक ही ऑरिजिन वाला अनुरोध, जहां
site.example
के अनुरोधsite.example/foo.json
को हमेशा अनुमति दी जाएगी. - ये आपके सबडोमेन से शुरू होते हैं.
- उपयोगकर्ता एजेंट के साथ उपयोगकर्ता के इंटरैक्शन की वजह से हो सकते हैं. उदाहरण के लिए, सीधे तौर पर नेविगेट करने या किसी बुकमार्क पर क्लिक करने से.
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True # Allow this request
तीसरा चरण: आसानी से टॉप-लेवल पर नेविगेट करने और iframing की अनुमति देना
यह पक्का करने के लिए कि आपकी साइट को अब भी दूसरी साइटों से लिंक किया जा सके, आपको आसान (HTTP GET
) टॉप-लेवल नेविगेशन की अनुमति देनी होगी.
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
# <object> and <embed> send navigation requests, which we disallow.
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True # Allow this request
चौथा चरण: उन एंडपॉइंट से ऑप्ट आउट करना जो अलग-अलग साइट पर आने वाले ट्रैफ़िक को दिखाने के लिए बने हैं (ज़रूरी नहीं)
कुछ मामलों में, आपका ऐप्लिकेशन ऐसे संसाधन उपलब्ध करा सकता है जिन्हें क्रॉस-साइट लोड किया जाना है. इन संसाधनों को हर पाथ या हर एंडपॉइंट के हिसाब से छूट दी जानी चाहिए. ऐसे एंडपॉइंट के उदाहरण यहां दिए गए हैं:
- ऐसे एंडपॉइंट जिन्हें अलग-अलग ऑरिजिन से ऐक्सेस किया जाना है: अगर आपका ऐप्लिकेशन ऐसे एंडपॉइंट दिखा रहा है जिन पर
CORS
चालू है, तो आपको उन्हें संसाधन अलग करने की सुविधा से साफ़ तौर पर ऑप्ट आउट करना होगा. इससे यह पक्का किया जा सकेगा कि इन एंडपॉइंट पर अलग-अलग साइटों से अनुरोध किए जा सकें. - सार्वजनिक संसाधन (जैसे कि इमेज, स्टाइल वगैरह): सार्वजनिक और ऐसे संसाधनों को भी छूट दी जा सकती है जिन्हें अन्य साइटों से क्रॉस-ऑरिजिन के तौर पर लोड किया जा सकता है. हालांकि, इन संसाधनों की पुष्टि नहीं की गई होनी चाहिए.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
पांचवां चरण: ऐसे सभी अनुरोधों को अस्वीकार करें जो एक से दूसरी साइट से किए गए हैं, न कि नेविगेशन से जुड़े
क्रॉस-साइट के किसी भी अन्य अनुरोध को, रिसॉर्स आइसोलेशन की इस नीति के तहत अस्वीकार कर दिया जाएगा. ऐसा होने पर, आपके ऐप्लिकेशन को क्रॉस-साइट हमलों से सुरक्षित रखा जाएगा.
उदाहरण: नीचे दिए गए कोड में, सर्वर पर संसाधन आइसोलेशन की मज़बूत नीति को पूरी तरह से लागू किया गया है. इसके अलावा, यह एक मिडलवेयर के तौर पर भी दिखाया गया है, जो नुकसान पहुंचाने वाले क्रॉस-साइट रिसॉर्स के अनुरोधों को अस्वीकार करने के लिए, सामान्य नेविगेशन अनुरोधों को अनुमति देता है:
# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
# Allow requests from browsers which don't send Fetch Metadata
if not req['sec-fetch-site']:
return True
# Allow same-site and browser-initiated requests
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True
# Allow simple top-level navigations except <object> and <embed>
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True
# [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
# Reject all other requests that are cross-site and not navigational
return False
रिसॉर्स आइसोलेशन की नीति लागू करना
- ऊपर दिए गए कोड स्निपेट जैसे मॉड्यूल को इंस्टॉल करें, ताकि आपकी साइट के व्यवहार को लॉग और मॉनिटर किया जा सके. साथ ही, यह पक्का किया जा सके कि पाबंदियों का असर किसी भी मान्य ट्रैफ़िक पर न पड़े.
- मान्य क्रॉस-ऑरिजिन एंडपॉइंट को छूट देकर, संभावित उल्लंघनों को ठीक करें.
- नीति का पालन न करने वाले अनुरोधों को हटाकर, नीति को लागू करें.
नीति के उल्लंघनों की पहचान करना और उन्हें ठीक करना
हमारा सुझाव है कि आप अपनी नीति को बिना किसी असर के टेस्ट करें. इसके लिए, पहले अपने सर्वर-साइड कोड में रिपोर्टिंग मोड में नीति को चालू करें. इसके अलावा, इस लॉजिक को मिडलवेयर या रिवर्स प्रॉक्सी में लागू किया जा सकता है. यह उन उल्लंघनों को लॉग करता है जो आपकी नीति के प्रोडक्शन ट्रैफ़िक पर लागू होने पर हो सकते हैं.
Google में, मेटाडेटा के संसाधन अलग करने से जुड़ी नीति फ़ेच करने के हमारे अनुभव से, ज़्यादातर ऐप्लिकेशन डिफ़ॉल्ट रूप से इस तरह की नीति के साथ काम करते हैं. कई बार क्रॉस-साइट ट्रैफ़िक की अनुमति देने के लिए, एंडपॉइंट को छूट देने की ज़रूरत भी बहुत कम होती है.
रिसॉर्स आइसोलेशन की नीति लागू करना
जब आप यह जांच कर लें कि आपकी नीति सही प्रोडक्शन ट्रैफ़िक पर असर नहीं डाल रही है, तब आप पाबंदियां लागू करने के लिए तैयार हैं. इसके बाद, आपको गारंटी देनी है कि दूसरी साइटें आपके संसाधनों का अनुरोध नहीं कर सकेंगी. साथ ही, आपके उपयोगकर्ताओं को क्रॉस-साइट हमलों से भी सुरक्षित रख पाएंगी.
इसके बारे में और पढ़ें
- W3C फ़ेच मेटाडेटा अनुरोध के हेडर की खास बातें
- Fetch Metadata Playground
- Google I/O टॉक: मॉडर्न प्लैटफ़ॉर्म सुविधाओं से वेब ऐप्लिकेशन सुरक्षित करना (Slides)