मैं एक आवेदन लिख रहा हूं (Django, ऐसा होता है) और मैं सिर्फ एक विचार चाहता हूं कि वास्तव में "सीएसआरएफ टोकन" क्या है और यह डेटा की सुरक्षा कैसे करता है। यदि आप CSRF टोकन का उपयोग नहीं करते हैं तो क्या पोस्ट डेटा सुरक्षित नहीं है?
मैं एक आवेदन लिख रहा हूं (Django, ऐसा होता है) और मैं सिर्फ एक विचार चाहता हूं कि वास्तव में "सीएसआरएफ टोकन" क्या है और यह डेटा की सुरक्षा कैसे करता है। यदि आप CSRF टोकन का उपयोग नहीं करते हैं तो क्या पोस्ट डेटा सुरक्षित नहीं है?
जवाबों:
www.mybank.com
mybank.com
(वैचारिक रूप से) फॉर्म का अनुरोध होगा http://www.mybank.com/transfer?to=<SomeAccountnumber>;amount=<SomeAmount>
। (आपका खाता नंबर आवश्यक नहीं है, क्योंकि यह आपके लॉगिन से निहित है।)www.cute-cat-pictures.org
, यह नहीं जानते कि यह एक दुर्भावनापूर्ण साइट है।mybank.com
(कुछ भाग्य की आवश्यकता है!), तो वे अपने पेज पर अनुरोध शामिल कर सकते हैं जैसे http://www.mybank.com/transfer?to=123456;amount=10000
( 123456
उनके केमैन आइलैंड्स खाते की संख्या कहां है) और 10000
एक राशि है जिसे आपने पहले सोचा था कि आपके पास खुशी थी)।www.cute-cat-pictures.org
पृष्ठ को पुनः प्राप्त कर लिया है , इसलिए आपका ब्राउज़र वह अनुरोध कर देगा।www.mybank.com
कुकी के साथ अनुरोध भेजेगा और यह पूरी तरह से वैध लगेगा। वहाँ तुम्हारा पैसा जाता है!यह CSRF टोकन के बिना दुनिया है ।
अब CSRF टोकन के साथ बेहतर के लिए :
http://www.mybank.com/transfer?to=123456;amount=10000;token=31415926535897932384626433832795028841971
:।mybank.com
स्वयं के वेब पेज पर शामिल होगी जब वे इसे आपको प्रदान करेंगे। यह हर बार अलग होता है कि वे किसी भी पेज को किसी को भी परोसते हैं।www.mybank.com
।परिणाम: आप अपनी 10000
मौद्रिक इकाइयाँ रखते हैं। मेरा सुझाव है कि आप इसमें से कुछ विकिपीडिया को दान करें।
(आपकी माइलेज भिन्न हो सकती है।)
पढ़ने लायक टिप्पणी से EDIT:
यह ध्यान देने योग्य होगा कि HTTP एक्सेस कंट्रोल के कारण स्क्रिप्ट www.cute-cat-pictures.org
आमतौर पर आपके एंटी-सीएसआरएफ टोकन तक नहीं पहुंच पाती है www.mybank.com
। यह नोट कुछ लोगों के लिए महत्वपूर्ण है जो अनुचित रूप से Access-Control-Allow-Origin: *
हर वेबसाइट की प्रतिक्रिया के लिए हेडर भेजते हैं, बिना यह जाने कि यह किस लिए है, क्योंकि वे किसी अन्य वेबसाइट से एपीआई का उपयोग नहीं कर सकते हैं।
www.cute-cat-pictures.org
आमतौर पर आपके एंटी-सीएसआरएफ टोकन तक नहीं पहुंच पाती है www.mybank.com
। यह नोट कुछ लोगों के लिए महत्वपूर्ण है जो अनुचित रूप से Access-Control-Allow-Origin: *
हर वेबसाइट की प्रतिक्रिया के लिए हेडर भेजते हैं, बिना यह जाने कि यह किस लिए है, क्योंकि वे किसी अन्य वेबसाइट से एपीआई का उपयोग नहीं कर सकते हैं।
हां, पोस्ट डेटा सुरक्षित है। लेकिन उस डेटा की उत्पत्ति नहीं है। इस तरह से कोई व्यक्ति जेएस के साथ उपयोगकर्ता को आपकी साइट पर लॉग इन करते समय हमला कर सकता है, जबकि हमलावर का वेब पेज ब्राउज़ कर रहा है।
इसे रोकने के लिए, django कुकी में एक यादृच्छिक कुंजी भेजेगा, और डेटा बनाएगा। फिर, जब उपयोगकर्ता POST करते हैं, तो यह जांच करेगा कि क्या दो कुंजी समान हैं। ऐसे मामले में जहां उपयोगकर्ता को बरगलाया जाता है, तीसरी पार्टी की वेबसाइट आपकी साइट की कुकीज़ प्राप्त नहीं कर सकती है, इस प्रकार यह त्रुटि उत्पन्न करती है।
जब यह प्रपत्र पृष्ठ बनाता है तो साइट एक अद्वितीय टोकन उत्पन्न करती है। यह टोकन सर्वर पर डेटा वापस पोस्ट / प्राप्त करने के लिए आवश्यक है।
चूंकि टोकन आपकी साइट द्वारा जनरेट किया गया है और केवल तभी प्रदान किया जाता है जब फॉर्म वाला पेज जेनरेट होता है, कुछ अन्य साइट आपके फॉर्म की नकल नहीं कर सकती - उनके पास टोकन नहीं होगा और इसलिए वे आपकी साइट पर पोस्ट नहीं कर सकते हैं।
क्लाउड अंडर ब्लॉग में CSRF टोकन की अच्छी व्याख्या है।
कल्पना कीजिए कि आपके पास एक वेबसाइट थी, जो एक सरलीकृत ट्विटर की तरह थी, जिसे एक.com पर होस्ट किया गया था। उपयोगकर्ताओं में हस्ताक्षर किए गए कुछ पाठ (एक ट्वीट) को एक फॉर्म में दर्ज कर सकते हैं जो सर्वर पर एक पोस्ट अनुरोध के रूप में भेजा जा रहा है और सबमिट बटन पर हिट होने पर प्रकाशित होता है। सर्वर पर उपयोगकर्ता को उनके अद्वितीय सत्र आईडी वाले कुकी द्वारा पहचाना जाता है, इसलिए आपका सर्वर जानता है कि ट्वीट किसने पोस्ट किया है।
फार्म उतना ही सरल हो सकता है:
<form action="http://a.com/tweet" method="POST"> <input type="text" name="tweet"> <input type="submit"> </form>
अब कल्पना कीजिए, एक बुरा आदमी अपनी दुर्भावनापूर्ण वेबसाइट पर इस फॉर्म को कॉपी और पेस्ट करता है, आइए b.com कहते हैं। पर्चा अभी भी काम करेगा। जब तक किसी उपयोगकर्ता को आपके ट्विटर पर साइन इन किया जाता है (यानी उन्हें a.com के लिए एक वैध सत्र कुकी मिल जाती है), तब तक POST अनुरोध भेजा
http://a.com/tweet
और संसाधित किया जाएगा जब उपयोगकर्ता सबमिट बटन पर क्लिक करता है।अब तक यह एक बड़ा मुद्दा नहीं है जब तक कि उपयोगकर्ता को इस बारे में अवगत कराया जाता है कि फॉर्म वास्तव में क्या करता है, लेकिन क्या होगा यदि हमारा बुरा आदमी इस तरह से फॉर्म को ट्विस्ट करता है:
<form action="https://example.com/tweet" method="POST"> <input type="hidden" name="tweet" value="Buy great products at http://b.com/#iambad"> <input type="submit" value="Click to win!"> </form>
अब, यदि आपका कोई उपयोगकर्ता बुरे आदमी की वेबसाइट पर समाप्त होता है और "जीतने के लिए क्लिक करें" हिट करता है! बटन, प्रपत्र आपकी वेबसाइट पर प्रस्तुत किया जाता है, उपयोगकर्ता कुकी में सत्र आईडी द्वारा सही ढंग से पहचाना जाता है और छिपा हुआ ट्वीट प्रकाशित हो जाता है।
यदि हमारा बुरा आदमी और भी बुरा था, तो वह निर्दोष उपयोगकर्ता को यह फ़ॉर्म सबमिट कर देगा जैसे ही वे जावास्क्रिप्ट का उपयोग करके अपना वेब पेज खोलते हैं, शायद एक अदृश्य आइफ्रेम में पूरी तरह से छिपा हुआ हो। यह मूल रूप से क्रॉस-साइट अनुरोध जालसाजी है।
एक फॉर्म आसानी से हर जगह से हर जगह जमा किया जा सकता है। आम तौर पर यह एक सामान्य विशेषता है, लेकिन कई और मामले हैं जहां यह महत्वपूर्ण है कि केवल उस फॉर्म को डोमेन से सबमिट किया जाए जहां वह है।
यदि आपका वेब एप्लिकेशन POST और GET अनुरोधों (जैसे PHP में $ _POST के बजाय $ _REQUEST का उपयोग करके) के बीच अंतर नहीं करता है, तो हालात और भी बदतर हैं। ऐसा मत करो!
<img src="http://a.com/tweet?tweet=This+is+really+bad">
दुर्भावनापूर्ण वेबसाइट या यहां तक कि ईमेल में एम्बेड किए गए डेटा परिवर्तन अनुरोधों को जितना आसान हो सके प्रस्तुत किया जा सकता है ।मैं यह कैसे सुनिश्चित कर सकता हूं कि कोई फॉर्म केवल मेरी अपनी वेबसाइट से सबमिट किया जा सकता है? यह वह जगह है जहाँ CSRF टोकन आता है। CSRF टोकन एक यादृच्छिक, कठोर-से-अनुमानित स्ट्रिंग है। आपके द्वारा सुरक्षित किए जाने वाले फ़ॉर्म वाले पृष्ठ पर, सर्वर एक यादृच्छिक स्ट्रिंग, CSRF टोकन उत्पन्न करेगा, इसे एक छिपे हुए फ़ील्ड के रूप में जोड़ें और इसे किसी तरह याद भी रखें, या तो इसे सत्र में संग्रहीत करके या कुकी सेट करके मान युक्त। अब फॉर्म इस तरह दिखेगा:
<form action="https://example.com/tweet" method="POST"> <input type="hidden" name="csrf-token" value="nc98P987bcpncYhoadjoiydc9ajDlcn"> <input type="text" name="tweet"> <input type="submit"> </form>
जब उपयोगकर्ता प्रपत्र सबमिट करता है, तो सर्वर को केवल सर्वर द्वारा याद किए गए CSRF टोकन के साथ पोस्ट किए गए फ़ील्ड csrf-token (नाम से कोई फर्क नहीं पड़ता) के मूल्य की तुलना करनी होती है। यदि दोनों स्ट्रिंग्स समान हैं, तो सर्वर प्रपत्र को संसाधित करना जारी रख सकता है। अन्यथा सर्वर को तुरंत फॉर्म को संसाधित करना बंद कर देना चाहिए और एक त्रुटि के साथ जवाब देना चाहिए।
यह काम क्यों करता है? ऊपर हमारे उदाहरण से खराब आदमी CSRF टोकन प्राप्त करने में असमर्थ होने के कई कारण हैं:
हमारे पेज से स्थैतिक स्रोत कोड को एक अलग वेबसाइट पर कॉपी करना बेकार होगा, क्योंकि प्रत्येक उपयोगकर्ता के साथ छिपे हुए फ़ील्ड का मूल्य बदल जाता है। वर्तमान उपयोगकर्ता के CSRF टोकन को जानने वाले बुरे व्यक्ति की वेबसाइट के बिना आपका सर्वर हमेशा POST अनुरोध को अस्वीकार करेगा।
क्योंकि बुरे आदमी का दुर्भावनापूर्ण पृष्ठ आपके उपयोगकर्ता के ब्राउज़र द्वारा किसी भिन्न डोमेन (a.com के बजाय b.com) से लोड किया गया है, बुरे व्यक्ति के पास जावास्क्रिप्ट कोड करने का कोई मौका नहीं है, जिससे सामग्री लोड होती है और इसलिए हमारे उपयोगकर्ता के वर्तमान CSRF टोकन से आपका वेबसाइट। ऐसा इसलिए है क्योंकि वेब ब्राउज़र डिफ़ॉल्ट रूप से क्रॉस-डोमेन AJAX अनुरोधों की अनुमति नहीं देते हैं।
खराब आदमी आपके सर्वर द्वारा कुकी सेट तक पहुंचने में असमर्थ है, क्योंकि डोमेन मेल नहीं खाते।
मुझे क्रॉस-साइट अनुरोध जालसाजी के खिलाफ कब रक्षा करनी चाहिए? यदि आप यह सुनिश्चित कर सकते हैं कि आप ऊपर वर्णित के रूप में GET, POST और अन्य अनुरोध विधियों को नहीं मिलाते हैं, तो डिफ़ॉल्ट रूप से सभी POST अनुरोधों की सुरक्षा के लिए एक अच्छी शुरुआत होगी।
आपको PUT और DELETE अनुरोधों की रक्षा करने की आवश्यकता नहीं है, क्योंकि जैसा कि ऊपर बताया गया है, उन तरीकों का उपयोग करके ब्राउज़र द्वारा एक मानक HTML फॉर्म जमा नहीं किया जा सकता है।
दूसरी ओर जावास्क्रिप्ट वास्तव में अन्य प्रकार के अनुरोध कर सकती है, जैसे jQuery के $ .ajax () फ़ंक्शन का उपयोग करना, लेकिन याद रखें, AJAX के अनुरोधों के लिए डोमेन से मेल खाना चाहिए (जब तक आप स्पष्ट रूप से अपने वेब सर्वर को अन्यथा कॉन्फ़िगर नहीं करते हैं) ।
इसका मतलब है, अक्सर आपको AJAX अनुरोधों में CSRF टोकन जोड़ने की आवश्यकता नहीं होती है, भले ही वे POST अनुरोध हों, लेकिन आपको यह सुनिश्चित करना होगा कि आप अपने वेब अनुप्रयोग में केवल CSRF चेक को बायपास करें यदि POST अनुरोध वास्तव में है AJAX का अनुरोध। आप एक्स-रिक्वेस्टेड-विथ हेडर की उपस्थिति की तलाश कर सकते हैं, जिसमें AJAX के अनुरोध आमतौर पर शामिल होते हैं। आप एक अन्य कस्टम हेडर भी सेट कर सकते हैं और सर्वर साइड पर इसकी उपस्थिति के लिए जाँच कर सकते हैं। यह सुरक्षित है, क्योंकि एक ब्राउज़र नियमित HTML फॉर्म सबमिशन (ऊपर देखें) में कस्टम हेडर नहीं जोड़ेगा, इसलिए श्री बैड गाइ के लिए इस व्यवहार को एक फॉर्म के साथ अनुकरण करने का कोई मौका नहीं है।
यदि आप AJAX अनुरोधों के बारे में संदेह में हैं, क्योंकि किसी कारण से आप X-Requested-With जैसे शीर्ष लेख के लिए जाँच नहीं कर सकते हैं, तो बस अपने CSRF उत्पन्न किए गए CSRF को अपने जावास्क्रिप्ट में पास करें और AJAX अनुरोध में टोकन जोड़ें। इसे करने के कई तरीके हैं; या तो इसे नियमित रूप से HTML फॉर्म की तरह पेलोड में जोड़ें, या AJAX अनुरोध में एक कस्टम हेडर जोड़ें। जब तक आपका सर्वर जानता है कि आने वाले अनुरोध में उसे कहां देखना है और वह इसे उस मूल मूल्य से तुलना करने में सक्षम है जिसे वह सत्र या कुकी से याद करता है, तो आप क्रमबद्ध हैं।
इस सब की जड़ यह सुनिश्चित करना है कि अनुरोध साइट के वास्तविक उपयोगकर्ताओं से आ रहे हैं। एक सीएसआरएफ टोकन रूपों के लिए उत्पन्न होता है और इसे उपयोगकर्ता के सत्रों से जुड़ा होना चाहिए। इसका उपयोग सर्वर को अनुरोध भेजने के लिए किया जाता है, जिसमें टोकन उन्हें मान्य करता है। यह csrf के खिलाफ सुरक्षा का एक तरीका है, दूसरा रेफरल हेडर की जाँच करेगा।