CSRF की रोकथाम के कुकीज़ को कुकीज़ में डालना आम क्यों है?


284

मैं सीएसआरएफ के साथ पूरे मामले को समझने की कोशिश कर रहा हूं और इसे रोकने के उचित तरीके। (संसाधन मैंने पढ़े हैं, समझे हैं, और इससे सहमत हैं: OWASP CSRF निरोध चेट शीट , CSRF के बारे में प्रश्न ।)

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

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

मेरे सवाल पर, जो उस राउंडट्रिप पर उस सीएसआरएफ टोकन के लिए इस्तेमाल की जाने वाली विशिष्ट परिवहन पद्धति के बारे में है।

यह आम लगता है (जैसे कि AngularJS , Django , रेल्स ) में CSRF टोकन को सर्वर से क्लाइंट के रूप में कुकी (यानी सेट-कुकी हेडर में) भेजने के लिए, और फिर क्लाइंट में जावास्क्रिप्ट को कुकी से बाहर खुरच कर संलग्न करें। सर्वर पर वापस भेजने के लिए एक अलग XSRF-TOKEN हेडर के रूप में।

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

CSRF टोकन के लिए डाउनस्ट्रीम परिवहन के रूप में सेट-कुकी का उपयोग करना इतना आम क्यों है / यह एक अच्छा विचार क्यों है? मुझे लगता है कि इन सभी रूपरेखाओं के लेखकों ने अपने विकल्पों पर ध्यान से विचार किया और यह गलत नहीं हुआ। लेकिन पहली नज़र में, कुकीज़ का उपयोग करने के लिए चारों ओर काम करने के लिए जो आवश्यक रूप से कुकीज़ पर एक डिज़ाइन सीमा है, बेतरतीब लगता है। वास्तव में, यदि आपने राउंडट्रिप ट्रांसपोर्ट (सेट-कुकी: सर्वर के लिए हेडर डाउनस्ट्रीम) का उपयोग किया है तो ब्राउज़र को CSRF टोकन बताने के लिए, और कुकी: ब्राउजर के लिए हेडर अपस्ट्रीम को सर्वर में वापस करने के लिए) आप अपनी भेद्यता का संकेत देंगे। ठीक करने की कोशिश कर रहे हैं।

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


यह सही मौके पर एक बड़ा सवाल है।
काटा

जवाबों:


263

एक अच्छा कारण, जिस पर आपने छुआ है, वह यह है कि एक बार CSRF कुकी प्राप्त हो जाने के बाद, यह नियमित रूप से और AJAX POSTs दोनों में उपयोग के लिए क्लाइंट स्क्रिप्ट में पूरे अनुप्रयोग में उपयोग के लिए उपलब्ध है। यह जावास्क्रिप्ट भारी एप्लिकेशन में समझ में आएगा जैसे कि AngularJS द्वारा नियुक्त एक (AngularJS का उपयोग करने के लिए यह आवश्यक नहीं है कि आवेदन एक ही पृष्ठ ऐप होगा, इसलिए यह उपयोगी होगा जहां राज्य को विभिन्न पृष्ठ अनुरोधों के बीच प्रवाह करना होगा जहां CSRF मान आम तौर पर ब्राउज़र में बनी नहीं रह सकती)।

प्रत्येक दृष्टिकोण के कुछ पेशेवरों और विपक्षों के लिए एक विशिष्ट अनुप्रयोग में निम्नलिखित परिदृश्यों और प्रक्रियाओं पर विचार करें। ये सिंक्रोनाइज़र टोकन पैटर्न पर आधारित हैं ।

बॉडी अप्रोच का अनुरोध करें

  1. उपयोगकर्ता सफलतापूर्वक लॉग इन करता है।
  2. सर्वर, कुकी जारी करता है।
  3. उपयोगकर्ता प्रपत्र पर नेविगेट करने के लिए क्लिक करता है।
  4. यदि इस सत्र के लिए अभी तक उत्पन्न नहीं हुआ है, तो सर्वर CSRF टोकन उत्पन्न करता है, इसे उपयोगकर्ता सत्र के खिलाफ संग्रहीत करता है और इसे एक छिपे हुए क्षेत्र में आउटपुट करता है।
  5. उपयोगकर्ता सबमिट करता है।
  6. सर्वर छुपा फ़ील्ड मिलान सत्र संग्रहीत टोकन की जाँच करता है।

लाभ:

  • लागू करने के लिए सरल।
  • AJAX के साथ काम करता है।
  • रूपों के साथ काम करता है।
  • कुकी वास्तव में केवल HTTP हो सकती है ।

नुकसान:

  • सभी रूपों को HTML में छिपे हुए फ़ील्ड को आउटपुट करना होगा।
  • किसी भी AJAX पोस्ट में मूल्य शामिल होना चाहिए।
  • पृष्ठ को पहले से पता होना चाहिए कि इसे CSRF टोकन की आवश्यकता है इसलिए इसे पृष्ठ सामग्री में शामिल किया जा सकता है, इसलिए सभी पृष्ठों में कहीं न कहीं टोकन मूल्य होना चाहिए, जिससे इसे किसी बड़ी साइट पर लागू करने में समय लग सकता है।

कस्टम HTTP हैडर (डाउनस्ट्रीम)

  1. उपयोगकर्ता सफलतापूर्वक लॉग इन करता है।
  2. सर्वर, कुकी जारी करता है।
  3. उपयोगकर्ता प्रपत्र पर नेविगेट करने के लिए क्लिक करता है।
  4. ब्राउज़र में पेज लोड होता है, फिर एक AJAX अनुरोध CSRF टोकन को पुनः प्राप्त करने के लिए किया जाता है।
  5. सर्वर CSRF टोकन उत्पन्न करता है (यदि सत्र के लिए पहले से उत्पन्न नहीं है), तो इसे उपयोगकर्ता सत्र के विरुद्ध संग्रहीत करता है और इसे हेडर पर आउटपुट करता है।
  6. उपयोगकर्ता सबमिट फॉर्म (टोकन को छिपे हुए फ़ील्ड के माध्यम से भेजा जाता है)।
  7. सर्वर छुपा फ़ील्ड मिलान सत्र संग्रहीत टोकन की जाँच करता है।

लाभ:

  • AJAX के साथ काम करता है।
  • कुकी केवल HTTP हो सकती है ।

नुकसान:

  • शीर्षक मान प्राप्त करने के लिए AJAX अनुरोध के बिना काम नहीं करता है।
  • सभी रूपों को गतिशील रूप से अपने HTML में जोड़ा जाना चाहिए।
  • किसी भी AJAX पोस्ट में मूल्य शामिल होना चाहिए।
  • CSRF टोकन प्राप्त करने के लिए पृष्ठ को पहले AJAX अनुरोध करना होगा, इसलिए इसका अर्थ होगा कि हर बार एक अतिरिक्त राउंड ट्रिप।
  • हो सकता है कि केवल पृष्ठ के लिए टोकन का उत्पादन हो, जो अतिरिक्त अनुरोध को बचाएगा।

कस्टम HTTP हैडर (अपस्ट्रीम)

  1. उपयोगकर्ता सफलतापूर्वक लॉग इन करता है।
  2. सर्वर, कुकी जारी करता है।
  3. उपयोगकर्ता प्रपत्र पर नेविगेट करने के लिए क्लिक करता है।
  4. यदि इस सत्र के लिए अभी तक उत्पन्न नहीं हुआ है, तो सर्वर CSRF टोकन उत्पन्न करता है, इसे उपयोगकर्ता सत्र के खिलाफ संग्रहीत करता है और इसे पृष्ठ सामग्री में कहीं आउटपुट करता है।
  5. AJAX (टोकन हेडर के माध्यम से भेजा जाता है) के माध्यम से उपयोगकर्ता सबमिट फॉर्म।
  6. सर्वर कस्टम हेडर मिलान सत्र संग्रहीत टोकन की जाँच करता है।

लाभ:

  • AJAX के साथ काम करता है।
  • कुकी केवल HTTP हो सकती है ।

नुकसान:

  • रूपों के साथ काम नहीं करता है।
  • सभी AJAX पोस्ट में हेडर शामिल होना चाहिए।

कस्टम HTTP हैडर (अपस्ट्रीम और डाउनस्ट्रीम)

  1. उपयोगकर्ता सफलतापूर्वक लॉग इन करता है।
  2. सर्वर, कुकी जारी करता है।
  3. उपयोगकर्ता प्रपत्र पर नेविगेट करने के लिए क्लिक करता है।
  4. ब्राउज़र में पेज लोड होता है, फिर एक AJAX अनुरोध CSRF टोकन को पुनः प्राप्त करने के लिए किया जाता है।
  5. सर्वर CSRF टोकन उत्पन्न करता है (यदि सत्र के लिए पहले से उत्पन्न नहीं है), तो इसे उपयोगकर्ता सत्र के विरुद्ध संग्रहीत करता है और इसे हेडर पर आउटपुट करता है।
  6. AJAX (टोकन हेडर के माध्यम से भेजा जाता है) के माध्यम से उपयोगकर्ता सबमिट फॉर्म।
  7. सर्वर कस्टम हेडर मिलान सत्र संग्रहीत टोकन की जाँच करता है।

लाभ:

  • AJAX के साथ काम करता है।
  • कुकी केवल HTTP हो सकती है ।

नुकसान:

  • रूपों के साथ काम नहीं करता है।
  • सभी AJAX पोस्ट में मूल्य भी शामिल होना चाहिए।
  • पृष्ठ को CRSF टोकन प्राप्त करने के लिए पहले AJAX अनुरोध करना होगा, इसलिए इसका मतलब होगा कि हर बार एक अतिरिक्त राउंड ट्रिप।

सेट-कुकी

  1. उपयोगकर्ता सफलतापूर्वक लॉग इन करता है।
  2. सर्वर, कुकी जारी करता है।
  3. उपयोगकर्ता प्रपत्र पर नेविगेट करने के लिए क्लिक करता है।
  4. सर्वर CSRF टोकन उत्पन्न करता है, इसे उपयोगकर्ता सत्र के खिलाफ संग्रहीत करता है और इसे कुकी के लिए आउटपुट करता है।
  5. उपयोगकर्ता प्रस्तुतियाँ AJAX या HTML फ़ॉर्म के माध्यम से बनाते हैं।
  6. सर्वर कस्टम हेडर (या हिडन फॉर्म फील्ड) की जाँच करता है जो संग्रहित टोकन से मेल खाता है।
  7. कुकी अतिरिक्त AJAX में उपयोग के लिए ब्राउज़र में उपलब्ध है और CSRF टोकन को पुनः प्राप्त करने के लिए सर्वर से अतिरिक्त अनुरोध के बिना फ़ॉर्म अनुरोध करता है।

लाभ:

  • लागू करने के लिए सरल।
  • AJAX के साथ काम करता है।
  • रूपों के साथ काम करता है।
  • जरूरी नहीं कि कुकी मूल्य प्राप्त करने के लिए AJAX अनुरोध की आवश्यकता हो। कोई भी HTTP अनुरोध इसे पुनः प्राप्त कर सकता है और इसे जावास्क्रिप्ट के माध्यम से सभी रूपों / AJAX अनुरोधों में जोड़ा जा सकता है।
  • एक बार CSRF टोकन को पुनः प्राप्त कर लिया गया है, क्योंकि यह एक कुकी में संग्रहीत होता है और अतिरिक्त अनुरोधों के बिना मूल्य का पुन: उपयोग किया जा सकता है।

नुकसान:

  • सभी रूपों को गतिशील रूप से अपने HTML में जोड़ा जाना चाहिए।
  • किसी भी AJAX पोस्ट में मूल्य शामिल होना चाहिए।
  • कुकी को हर अनुरोध के लिए प्रस्तुत किया जाएगा (अर्थात छवियों के लिए सभी जीईटी, सीएसएस, जेएस, आदि, जो कि सीएसआरएफ प्रक्रिया में शामिल नहीं हैं) अनुरोध आकार में वृद्धि कर रहे हैं।
  • कुकी केवल HTTP नहीं हो सकती ।

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

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


7
मुझे यकीन नहीं है कि मैं समझता हूं कि "AJAX अनुरोध CSRF टोकन को पुनः प्राप्त करने के लिए कैसे किया जाता है" (चरण 4 दोनों "कस्टम हेडर: डाउनस्ट्रीम" अनुभाग) सुरक्षित रूप से किया जा सकता है; चूंकि यह एक अलग अनुरोध है, सर्वर यह नहीं जानता कि यह किससे आ रहा है; यह कैसे पता चलेगा कि CSRF टोकन को विभाजित करना सुरक्षित है? यह मुझे लगता है कि यदि आप प्रारंभिक पृष्ठ लोड से टोकन प्राप्त नहीं कर सकते हैं, तो आप खो देते हैं (जो कस्टम डाउनस्ट्रीम प्रतिक्रिया हेडर को नॉन-स्टार्टर बनाता है, दुर्भाग्य से)।
22

6
क्योंकि forger में सत्र कुकी नहीं होगी। उनका अपना सत्र कुकी हो सकता है, लेकिन CSRF टोकन सत्र से जुड़ा होने के कारण, उनका CSRF टोकन पीड़ित के मेल नहीं खाएगा।
सिल्वरलाइटफॉक्स

32
सीएसआरएफ हमले की मेरी समझ में, फोरजर में मेरा सत्र कुकी है। ठीक है, उन्हें वास्तव में कुकी देखने को नहीं मिलती है , लेकिन उनके पास उनके जाली अनुरोधों को प्रदान करने की क्षमता है, क्योंकि अनुरोध मेरे ब्राउज़र से आ रहे हैं और मेरा ब्राउज़र मेरे सत्र कुकी की आपूर्ति करता है। इसलिए सर्वर के दृष्टिकोण से, सत्र कुकी अकेले एक जाली अनुरोध से वैध अनुरोध को अलग नहीं कर सकता है। यह वास्तव में हमला है जिसे हम रोकने की कोशिश कर रहे हैं। BTW इस के माध्यम से बात करने में अपने धैर्य के लिए धन्यवाद, खासकर अगर मैं इस बारे में उलझन में हूँ।
मेटमैट

8
उनके पास कुकीज की आपूर्ति करने की क्षमता है, लेकिन वे उस प्रतिक्रिया को नहीं पढ़ सकते हैं जिसमें CSRF टोकन शामिल है।
सिल्वरलाइटफॉक्स

8
@metamatt necro के लिए क्षमा करें, लेकिन मैं इसे ऐसे लोगों के लिए करूंगा जो भटकते हैं। मेरी समझ में हमलावर के पास आमतौर पर प्रतिक्रिया तक पहुंच नहीं है। CSRF का उपयोग मुख्य रूप से सीधे डेटा एकत्र करने के बजाए, साइड इफेक्ट करने के लिए किया जाता है । उदाहरण के लिए, एक CSRF हमले की स्क्रिप्ट एक विशेषाधिकार प्राप्त उपयोगकर्ता को हमलावर के विशेषाधिकारों को बढ़ाने, सुरक्षा सेटिंग को अक्षम करने, या किसी विशिष्ट ईमेल पते पर स्थानांतरण भेजने के लिए लॉग-इन पेपैल उपयोगकर्ता को बाध्य करने के लिए मजबूर कर सकती है। इनमें से किसी भी मामले में हमलावर प्रतिक्रिया की परवाह नहीं करता है, जिसे अभी भी पीड़ित के ब्राउज़र में भेजा गया है; केवल हमले के परिणाम।
जोनाथनब्रुडर

61

ग्राहक को CSRF टोकन प्रदान करने के लिए एक कुकी का उपयोग करना एक सफल हमले की अनुमति नहीं देता है क्योंकि हमलावर कुकी के मूल्य को नहीं पढ़ सकता है और इसलिए इसे नहीं डाल सकता है जहां सर्वर-साइड CSRF सत्यापन की आवश्यकता होती है।

हमलावर अनुरोधकर्ताओं में दोनों टोकन टोकन और CSRF कुकी के साथ सर्वर के लिए अनुरोध करने में सक्षम होगा। लेकिन सर्वर अनुरोध हेडर में कुकी के रूप में सीएसआरएफ टोकन की तलाश नहीं कर रहा है, यह अनुरोध के पेलोड में लग रहा है। और यहां तक ​​कि अगर हमलावर को पता है कि पेलोड में सीएसआरएफ टोकन कहां रखा जाए, तो उन्हें वहां रखने के लिए इसका मूल्य पढ़ना होगा। लेकिन ब्राउज़र की क्रॉस-ऑरिजिन पॉलिसी लक्ष्य वेबसाइट से किसी भी कुकी मूल्य को पढ़ने से रोकती है।

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


हालांकि, निश्चित रूप से, एक हमलावर को पहली बार में कुकी को पढ़ने की आवश्यकता नहीं है। वे सिर्फ हैक की गई साइट पर एक छवि सम्मिलित कर सकते हैं src='bank.com/transfer?to=hacker&amount=1000जिसके साथ ब्राउज़र अनुरोध करेगा, उस साइट ( bank.com) के लिए संबंधित कुकीज़ के साथ पूरा करें ?
विकासशील

2
CSRF क्लाइंट पक्ष पर उपयोगकर्ता को मान्य करने के लिए है, और साइट की सुरक्षा के लिए आमतौर पर सर्वर साइड से समझौता करने के लिए नहीं जैसा कि आप सुझाव देते हैं।
टोंगफा

2
@ डेवेलियस को कुकी भेजना सीएसआरएफ सुरक्षा को संतुष्ट करने के लिए पर्याप्त नहीं है। कुकी में सर्वर द्वारा भेजा गया csrf टोकन होता है। वैध क्लाइंट को कुकी से बाहर csrf टोकन पढ़ना चाहिए, और फिर इसे अनुरोध में कहीं पास करना चाहिए, जैसे हेडर या पेलोड में। CSRF सुरक्षा जाँच करता है कि कुकी का मूल्य अनुरोध में मूल्य से मेल खाता है, अन्यथा अनुरोध अस्वीकार कर दिया गया है। इसलिए, हमलावर को कुकी को पढ़ने की आवश्यकता है।
विल एम।

1
यह उत्तर मूल पोस्टर के प्रश्न के बिंदु पर बहुत स्पष्ट था और बहुत स्पष्ट था। +1 धन्यवाद।
java-addict301

@ टोंगा - धन्यवाद, इससे मुझे बेहतर समझने में मदद मिली। क्या मुझे यह मानने का अधिकार है कि CSRF टोकन को हेडर में नहीं रखा जाना चाहिए? यह शरीर में कहीं होना चाहिए?
१२:२६ पर २२

10

उत्तर के रूप में मेरा सबसे अच्छा अनुमान: CSRF टोकन को सर्वर से ब्राउज़र तक नीचे लाने के लिए इन 3 विकल्पों पर विचार करें।

  1. अनुरोध निकाय में (HTTP शीर्ष लेख नहीं)।
  2. एक कस्टम HTTP हेडर में, सेट-कुकी नहीं।
  3. कुकी के रूप में, सेट-कुकी हेडर में।

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

दूसरा एक, कस्टम हेडर, आकर्षक है, लेकिन वास्तव में काम नहीं करता है, क्योंकि जेएस एक एक्सएचआर के लिए हेडर प्राप्त कर सकता है, जिसे इसे लागू किया गया है, यह उस पेज के लिए हेडर नहीं प्राप्त कर सकता है जिसे उसने लोड किया था

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


7
मैं स्पष्ट कह सकता हूं, इसका मतलब यह है कि कुकी httponly सही नहीं हो सकती है?
फोटॉन

1
केवल अजाक्स अनुरोधों के लिए (जहाँ जेएस को दूसरे चैनल में अगले अनुरोध पर इसे फिर से भेजने के लिए सीएसआरएफ कुकी के मूल्य को जानना होगा (या तो फॉर्म डेटा या हेडर के रूप में)। अगर सत्र कुकी पहले से ही संबंधित सत्र के बिना मूल्यवान नहीं है, तो सत्र कुकी पहले से ही HttpOnly (XSS से बचाव के लिए) होने पर csrf टोकन की आवश्यकता होने का कोई कारण नहीं है।
काउबर्ट

2

सत्र कुकी (जो मानक की तरह है) के अलावा, मैं अतिरिक्त कुकीज़ का उपयोग नहीं करना चाहता।

मुझे एक समाधान मिला, जो कई AJAX अनुरोधों के साथ सिंगल पेज वेब एप्लिकेशन (एसपीए) का निर्माण करते समय मेरे लिए काम करता है। नोट: मैं सर्वर साइड जावा और क्लाइंट साइड JQuery का उपयोग कर रहा हूं, लेकिन कोई जादूई चीजें नहीं हैं इसलिए मुझे लगता है कि यह सिद्धांत सभी लोकप्रिय प्रोग्रामिंग भाषाओं में लागू किया जा सकता है।

अतिरिक्त कुकीज़ के बिना मेरा समाधान सरल है:

ग्राहक की ओर

CSRF टोकन को स्टोर करें जो सर्वर द्वारा एक वैश्विक चर में एक सफल लॉगिन के बाद लौटाया जाता है (यदि आप वैश्विक भंडारण के बजाय वेब स्टोरेज का उपयोग करना चाहते हैं तो ठीक है)। प्रत्येक AJAX कॉल में X-CSRF-TOKEN हेडर की आपूर्ति करने के लिए JQuery को निर्देश दें।

मुख्य "इंडेक्स" पृष्ठ में यह जावास्क्रिप्ट स्निपेट है:

// Intialize global variable CSRF_TOKEN to empty sting. 
// This variable is set after a succesful login
window.CSRF_TOKEN = '';

// the supplied callback to .ajaxSend() is called before an Ajax request is sent
$( document ).ajaxSend( function( event, jqXHR ) {
    jqXHR.setRequestHeader('X-CSRF-TOKEN', window.CSRF_TOKEN);
}); 

सर्वर साइड

उत्तराधिकारी लॉगिन पर, एक यादृच्छिक (और लंबे समय तक) CSRF टोकन बनाएं, इसे सर्वर साइड सत्र में संग्रहीत करें और इसे क्लाइंट को वापस करें। सत्र में संग्रहीत मान के लिए X-CSRF-TOKEN हैडर मान की तुलना करके कुछ (संवेदनशील) आने वाले अनुरोधों को फ़िल्टर करें: यह मेल खाता है।

संवेदनशील AJAX कॉल (POST फॉर्म-डेटा और GET JSON-डेटा), और सर्वर साइड फ़िल्टर उन्हें पकड़ रहे हैं, एक / dataservice / * पथ के अंतर्गत हैं। लॉगिन अनुरोध फ़िल्टर को हिट नहीं करना चाहिए, इसलिए ये दूसरे रास्ते पर हैं। HTML, CSS, JS और छवि संसाधनों के लिए अनुरोध भी / डेटा सर्विस / * पथ पर नहीं हैं, इस प्रकार फ़िल्टर नहीं किए गए हैं। इनमें कुछ भी गुप्त नहीं है और कोई नुकसान नहीं कर सकता है, इसलिए यह ठीक है।

@WebFilter(urlPatterns = {"/dataservice/*"})
...
String sessionCSRFToken = req.getSession().getAttribute("CSRFToken") != null ? (String) req.getSession().getAttribute("CSRFToken") : null;
if (sessionCSRFToken == null || req.getHeader("X-CSRF-TOKEN") == null || !req.getHeader("X-CSRF-TOKEN").equals(sessionCSRFToken)) {
    resp.sendError(401);
} else
    chain.doFilter(request, response);
}   

मुझे लगता है कि आप लॉगिन अनुरोध पर सीएसआरएफ चाहते हैं। आप CSRF टोकन का उपयोग लॉगिन सत्र टोकन के रूप में भी कर रहे हैं। यह उन्हें अलग टोकन के रूप में भी काम करता है, और फिर आप किसी भी समापन बिंदु पर CSRF का उपयोग कर सकते हैं, चाहे उपयोगकर्ता लॉग इन हो या न हो।
टोंगफा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.