क्या devise's token_authenticatable सुरक्षित है?


79

मैं रेल एपीआई के साथ एक साधारण एपीआई बना रहा हूं, और यह सुनिश्चित करना चाहता हूं कि मैं यहां सही रास्ते पर हूं। मैं लॉगिन को संभालने के लिए डेविस का उपयोग कर रहा हूं, और डेविस के token_authenticatableविकल्प के साथ जाने का फैसला किया , जो एक एपीआई कुंजी बनाता है जिसे आपको प्रत्येक अनुरोध के साथ भेजने की आवश्यकता होती है।

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

मैं यहां पूरी तरह से गलत हो सकता हूं (और मुझे आशा है कि), क्या कोई समझा सकता है कि क्या इस तरह से प्रमाणित करना विश्वसनीय रूप से सुरक्षित है, और यदि एक अच्छा विकल्प नहीं है तो क्या होगा? कुल मिलाकर, मैं एक ऐसा रास्ता ढूंढ रहा हूं, जिसमें मैं उपयोगकर्ताओं को सुरक्षित रूप से फिर से ऑवर ऑवर मजबूर किए बिना एपीआई एक्सेस में 'साइन इन' रख सकता हूं।

जवाबों:


190

token_authenticatableसमय के हमलों के प्रति संवेदनशील है, जो इस ब्लॉग पोस्ट में बहुत अच्छी तरह से समझाया गया है । इन हमलों के कारण token_authenticatableडेविस 3.1 से हटा दिया गया था। अधिक जानकारी के लिए plataformatec ब्लॉग पोस्ट देखें ।

सबसे सुरक्षित टोकन प्रमाणीकरण तंत्र के लिए, टोकन:

  1. HTTPS के माध्यम से भेजा जाना चाहिए।

  2. क्रिप्टोग्राफिक ताकत का यादृच्छिक होना चाहिए।

  3. सुरक्षित रूप से तुलना की जानी चाहिए।

  4. सीधे डेटाबेस में संग्रहीत नहीं किया जाना चाहिए। टोकन के केवल एक हैश को वहां संग्रहीत किया जा सकता है। (याद रखें, टोकन = पासवर्ड। हम db में सीधे सादे पाठ में पासवर्ड स्टोर नहीं करते हैं?)

  5. कुछ तर्क के अनुसार समाप्त होना चाहिए।

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

मेरे उत्तर का विस्तार और व्याख्या:

  1. HTTPS का उपयोग करें । यह निश्चित रूप से सबसे महत्वपूर्ण बिंदु है क्योंकि यह स्निफर्स के साथ व्यवहार करता है।

    यदि आप HTTPS का उपयोग नहीं करते हैं, तो बहुत कुछ गलत हो सकता है। उदाहरण के लिए:

    • उपयोगकर्ता के क्रेडेंशियल्स (उपयोगकर्ता नाम / ईमेल / पासवर्ड) को सुरक्षित रूप से संचारित करने के लिए, आपको डाइजेस्ट प्रमाणीकरण का उपयोग करना होगा, लेकिन यह सिर्फ इन दिनों में कटौती नहीं करता है क्योंकि नमकीन राख को मजबूर किया जा सकता है

    • रेल 3 में, कुकीज़ को केवल बेस 64 एन्कोडिंग द्वारा हिलाया जाता है, ताकि वे आसानी से प्रकट हो सकें। अधिक जानकारी के लिए डिकोडिंग रेल सत्र कुकीज़ देखें ।

      4 रेल के बाद से, कुकी स्टोर एन्क्रिप्टेड है, इसलिए डेटा एक डिजीटल रूप से सत्यापित और अपठनीय दोनों है। कुकीज़ तब तक सुरक्षित होनी चाहिए जब तक कि आपका secret_key_baseरिसाव न हो।

  2. अपना टोकन जनरेट करें:

    • SecureRandom.hex केवल अगर आप रूबी 2.5+ पर हैं।
    • मणि sysrandomयदि आप एक पुराने रूबी पर हैं।

    यह क्यों आवश्यक है, इस बारे में स्पष्टीकरण के लिए, मैं विभिन्न प्रोग्रामिंग भाषाओं में सुरक्षित यादृच्छिक संख्या उत्पन्न करने केsysrandom लिए ब्लॉग की README और ब्लॉग पोस्ट को पढ़ने का सुझाव देता हूं ।

  3. उपयोगकर्ता की आईडी, ईमेल या कुछ अन्य विशेषता का उपयोग करके उपयोगकर्ता रिकॉर्ड का पता लगाएं। फिर, अनुरोध के टोकन के साथ उस उपयोगकर्ता के टोकन की तुलना करें Devise.secure_compare(user.auth_token, params[:auth_token]। यदि आप रेल 4.2.1+ पर हैं, तो आप भी उपयोग कर सकते हैं ActiveSupport::SecurityUtils.secure_compare

    करो नहीं की तरह एक रेल खोजक के साथ उपयोगकर्ता रिकॉर्ड को खोजने के User.find_by(auth_token: params[:auth_token])। यह समय हमलों के लिए कमजोर है!

  4. यदि आप प्रति उपयोगकर्ता एक ही समय में कई एप्लिकेशन / सत्र करने जा रहे हैं, तो आपके पास दो विकल्प हैं:

    • डेटाबेस में अनएन्क्रिप्टेड टोकन स्टोर करें ताकि इसे उपकरणों के बीच साझा किया जा सके। यह एक बुरा अभ्यास है, लेकिन मुझे लगता है कि आप इसे UX के नाम पर कर सकते हैं (और यदि आप अपने कर्मचारियों को डीबी पहुंच के साथ भरोसा करते हैं)।

    • वर्तमान सत्र की अनुमति देने के लिए प्रति उपयोगकर्ता कई एन्क्रिप्टेड टोकन संग्रहीत करें। इसलिए यदि आप 2 अलग-अलग उपकरणों पर 2 सत्रों की अनुमति देना चाहते हैं, तो डेटाबेस में 2 अलग-अलग टोकन हैश रखें। यह विकल्प लागू करने के लिए थोड़ा कम सीधा है लेकिन यह निश्चित रूप से सुरक्षित है। इसमें आपके उपयोगकर्ताओं को अपने टोकन (जैसे GitHub और Facebook do) को रद्द करके विशिष्ट उपकरणों में वर्तमान सक्रिय सत्रों को समाप्त करने का विकल्प प्रदान करने की अनुमति देने का भी उल्टा है ।

  5. किसी प्रकार का तंत्र होना चाहिए जिससे टोकन समाप्त हो जाए। इस तंत्र को लागू करते समय UX और सुरक्षा के बीच व्यापार बंद को ध्यान में रखें।

    Google एक टोकन को समाप्त करता है यदि इसका उपयोग छह महीने तक नहीं किया गया है

    फेसबुक एक टोकन को समाप्त करता है यदि इसे दो महीने तक उपयोग नहीं किया गया है :

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

  6. अपने एन्क्रिप्टेड कुकी स्टोर का उपयोग करने के लिए रेल 4 पर अपग्रेड करें। यदि आप नहीं कर सकते हैं, तो अपने आप को कुकी स्टोर को एन्क्रिप्ट करें, जैसे कि यहां सुझाया गया है । एन्क्रिप्टेड कुकी स्टोर में प्रमाणीकरण टोकन संग्रहीत करने में कोई समस्या नहीं होगी।

आपके पास एक आकस्मिक योजना भी होनी चाहिए, उदाहरण के लिए, डेटाबेस में टोकन या प्रत्येक एकल टोकन को रीसेट करने के लिए एक रेक कार्य।

आरंभ करने के लिए, आप इस सार (डेविस के लेखकों में से एक) की जाँच कर सकते हैं कि डेविस के साथ टोकन प्रमाणीकरण कैसे लागू किया जाए। अंत में, एपीआई हासिल करने पर रेलसेक सहायक होना चाहिए।


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

1
जबकि दोनों विधियाँ एक यादृच्छिक स्ट्रिंग urlsafe_base64उत्पन्न करती हैं , एक url-safe स्ट्रिंग उत्पन्न करती हैं। यह सब नाम में है। जब तक आप अपने url ( जो आपको नहीं करना चाहिए ) में अपने टोकन का उपयोग करना चाहते हैं, तब तक उपयोग करें hex
अष्टकूट

2
टोकन! = पासवर्ड। प्लेन टेक्स्ट में टोकन स्टोर करने में कुछ भी गलत नहीं है। सादे पाठ में पासवर्ड संग्रहीत करने में समस्या यह है कि पासवर्ड का उपयोग कहीं और किया जा सकता है, यह आपके टोकन के मामले में नहीं होना चाहिए।
फेटफ्रॉग

2
@fatfrog No. टोकन == पासवर्ड। यदि किसी हैकर या असंतुष्ट कर्मचारी की आपके डेटाबेस तक पहुँच है, तो उसे एक निश्चित उपयोगकर्ता या व्यवस्थापक के रूप में प्रमाणित करने में सक्षम नहीं होना चाहिए।
अष्टाका

1
मैं असहमत हूं, अगर किसी हैकर या असंतुष्ट कर्मचारी की आपके डेटाबेस तक पहुंच है, तो टोकन आखिरी चीज है जिसके बारे में आपको चिंता करने की जरूरत है। आपके पास पहले से ही आपका डेटा है।
फेटफ्रॉग


3

आप अपने एपीआई के साथ रेल 4 का उपयोग करने की कोशिश कर सकते हैं , यह अधिक सुरक्षा प्रदान कर रहा है और डिवाइसेज़ 3.1.0rc का उपयोग कर सकता है

  • रेल 4.0 में, कई विशेषताओं को रत्नों में निकाला गया है।

    • ActiveRecord :: SessionStore
    • कार्रवाई कैशिंग
    • पेज कैशिंग
    • नेस्टेड टेम्पलेट्स के स्वचालित निर्भरता प्रबंधन के साथ रूसी गुड़िया-कैशिंग कुंजी-आधारित समाप्ति के माध्यम से।
      http://blog.envylabs.com/post/41711428227/rails-4-security-for-session-cookies
  • Devise 3.1.0.rc दोनों रेल 3.2 और रेल 4.0 पर चलती है। http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/

  • डेविस TokenAuthenticatable3.1.0rc में पदावनत है , लेकिन आप TokenAuthenticatable सुरक्षा के मुद्दे के लिए अपनी खुद की विधि का निर्माण कर सकते हैं । यह अधिक विश्वसनीय और सुरक्षित है।

टोकन के लिए, सेशन स्टोर आप http://ruby.railstutorial.org/chapters/sign-in-sign-out और http://blog.bigbinary.com/2013/03/19/cookies-on-rails के माध्यम से जा सकते हैं .html अधिक समझने योग्य है।

अंत में आपको इस तरह के एन्क्रिप्शन और डिक्रिप्शन के माध्यम से जाना चाहिए "अधिक सुरक्षित पाने के लिए संग्रहीत एन्क्रिप्टेड डेटा को डिक्रिप्ट करने में असमर्थ "।


क्या किसी के पास एक उदाहरण कस्टम निर्मित विकल्प है?
डैनियल मॉरिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.