REST API कॉल में पासवर्ड लगाना


31

मान लीजिए मेरे पास एक REST API है जिसका उपयोग पासवर्ड सेट / रीसेट करने के लिए भी किया जाता है। यह भी मान लें कि यह HTTPS कनेक्शन पर काम करता है। क्या कोई अच्छा कारण है कि पासवर्ड को कॉल पथ में नहीं रखा जाए, तो यह भी कहेंगे कि मैं इसे BASE64 में एन्कोड कर दूंगा?

इस तरह एक पासवर्ड रीसेट करने के लिए एक उदाहरण होगा:

http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD

मुझे लगता है कि BASE64 कोई एन्क्रिप्शन नहीं है, लेकिन मैं केवल इस मामले में सर्फिंग करने के लिए पासवर्ड की रक्षा करना चाहता हूं।


61
क्या आप GET पर दुष्प्रभाव का सुझाव दे रहे हैं? यह एक प्रोटोकॉल उल्लंघन है।
एबेन स्कोव पेडर्सन

27
यह वास्तव में REST resetpassword/OLDPASSWD/NEWPASSWDनहीं है क्योंकि संसाधन नहीं है। यह एक प्रक्रिया का एक आह्वान है। आपको सब कुछ URL में रखने की आवश्यकता नहीं है।
usr

5
@ ऐसबेन: किसने कहा कि यह एक GET है? ओपी ने ऐसा कभी नहीं कहा।
डेगनेलिस

3
सच है, वह सवाल में नहीं था। लेकिन नेट के जवाब के लिए उनकी टिप्पणी कहती है "अनुमान है कि मुझे POST का उपयोग करना होगा", इसलिए हम मान सकते हैं कि उन्होंने मूल रूप से GET के बारे में पूछा था। जैसा कि एसेन बताते हैं, ए बैड थिंग। केवल पढ़ना चाहिए।
मग

4
पासवर्ड रीसेट तंत्र के कई नुकसानों को समझाने वाला यह आनंदमय लेख संभवतः मामले को बेहतर ढंग से समझने में मदद कर सकता है।
9000

जवाबों:


76

एक अच्छा सर्वर इसके लिए भेजे गए सभी अनुरोधों को लॉग करता है, जिसमें URL (अक्सर, 'के बाद परिवर्तनीय भाग के बिना'), स्रोत IP, निष्पादन समय शामिल है ... क्या आप वास्तव में इस लॉग को चाहते हैं (संभवतः एक विस्तृत समूह द्वारा पढ़े गए) को समाहित करना पासवर्ड के रूप में गंभीर रूप से सुरक्षित जानकारी? Base64 उनके खिलाफ एक डाट नहीं है।


42
POST का उपयोग करने का यह सबसे बड़ा कारण नहीं है। यह एक सुरक्षा कारण है। लेकिन जब एसेन ने पहले ही टिप्पणी पर ध्यान दिया, तो एक GET के साथ राज्य बदलना इस तरह की बाकी सेवा का उल्लंघन है
पिनोइक

2
@BartFriederichs: और ब्राउज़र का इतिहास URL को याद रखेगा। और वेब पेज बनाकर गुमनाम रूप से पासवर्ड का एक गुच्छा आज़माएं, जिसमें उन सभी पासवर्डों के लिए एक लिंक है, जिन्हें आप आज़माना चाहते हैं, और Googlebot को वास्तविक अनुरोध करने दें ...
RemcoGerlich

2
"लेकिन जैसा कि एसेन ने पहले ही टिप्पणियों पर ध्यान दिया है, एक GET के साथ राज्य को बदलना इस तरह की एक आराम सेवा का उल्लंघन है" मैंने उस टिप्पणी पर भी ध्यान दिया, लेकिन मैं यह नहीं देखता कि किसी का यह कहना कहां है कि यह एक GET अनुरोध था। आप किसी URI में जानकारी एम्बेड कर सकते हैं और फिर भी उसे पोस्ट कर सकते हैं, आखिरकार। यह वास्तव में उचित नहीं है , हालांकि, चूंकि यूआरआई वास्तव में एक संसाधन का नामकरण नहीं कर रहा है।
यहोशू टेलर

नमस्ते, अच्छा जवाब है, लेकिन मैं "के बाद चर भाग के बिना" से असहमत हूं ? "" ... कई ऐसे हैं जो पूर्ण URL संग्रहीत करते हैं !!!
डेग्नेलिज़

2
"जीईटी के साथ बदलते राज्य इस तरह की एक आराम सेवा का उल्लंघन है" - चलो आरईएसटी में बहुत अधिक पकड़े न जाएं। GET के साथ स्थिति बदलना HTTP का उल्लंघन है ।
दान एलिस

69

आप जो प्रस्ताव दे रहे हैं वह न तो सुरक्षित है और न ही RESTful।

@Netch ने पहले ही लॉग के साथ समस्या का उल्लेख किया है, लेकिन इसमें एक और मुद्दा यह भी है कि आप HTTP द्वारा भेजे जा रहे पासवर्ड दिखा रहे हैं, जिससे किसी भी प्रकार के वायर स्निफर या मैन-इन-बीच हमले के साथ पासवर्ड कैप्चर करना तुच्छ हो जाता है।

जब आप REST का उपयोग करके GET अनुरोध करते हैं, तो URL के विभिन्न तत्व अधिक महीन दाने वाले तत्वों का प्रतिनिधित्व करते हैं। आपका URL ऐसे पढ़ता है जैसे आप एक OLDPASSWD का एक नया PASSWD भाग वापस कर रहे हैं जो एक रीसेटपास का हिस्सा है। इससे किसी भी प्रकार का अर्थ नहीं बनता है। डेटा को बचाने के लिए GET का उपयोग नहीं किया जाना चाहिए।

आपको कुछ इस तरह से करना चाहिए:

POST https://www.example.com/user/joe/resetpassword/
{oldpasswd:[data], newpasswd:[data]}

POST क्योंकि आप डेटा लिख ​​रहे हैं, और https क्योंकि आप इसे सूँघना नहीं चाहते हैं।

(यह वास्तव में कम-बार सुरक्षा है। पूर्ण न्यूनतम आपको करना चाहिए।)


2
क्या इसका मतलब क्लाइंट-साइड के पासवर्ड को हैशिंग नहीं करना होगा? क्या यह अनुशंसित है?
रोवन फ्रीमैन

1
नोट: यह पासवर्ड (लंबाई, आदि) आवश्यकताओं को लागू करने की अनुमति नहीं देगा। यह आपके मामले में एक मुद्दा नहीं हो सकता है, हालांकि यह एक लगातार सुरक्षा अभ्यास है, और कुछ संस्थाओं द्वारा कुछ समय की आवश्यकता है।
पॉल ड्रेपर

8
आप एक नया रिकॉर्ड नहीं बना रहे हैं, लेकिन एक मौजूदा रिकॉर्ड (आमतौर पर) को अपडेट कर रहे हैं, इसलिए यह POST के बजाय PUT होना चाहिए।

4
यह बहुत Restful नहीं है। रीसेटपासवर्ड एक संसाधन नहीं है जो उप-संसाधन को अकेले जाने दें। हालांकि, /user/joe/passwordथोड़ा बेहतर है लेकिन इष्टतम नहीं है।
व्हर्ल्विन

12
@CamilStaps नहीं, आप उपयोग नहीं कर सकते हैं PUT, क्योंकि PUTयह एक प्रकार का वृक्ष है। लेकिन जब पासवर्ड secretको supersecretसक्सेसफुल से बदल दिया गया है , तो वही रिक्वेस्ट दूसरी बार फेल हो जाएगी, इसलिए POSTयहां सही है। बेशक, जैसा कि @whirlwin ने कहा, इस संसाधन का नाम ठीक नहीं है।
रेसड्यूमन

60

प्रस्तावित योजना में कई क्षेत्रों में समस्याएं हैं।

सुरक्षा

URL पथ अक्सर लॉग होते हैं; रास्ते में बिना पासवर्ड के पासवर्ड डालना खराब चलन है।

एचटीटीपी

प्रमाणीकरण शीर्षक में प्रमाणीकरण / प्राधिकरण जानकारी दिखाई देनी चाहिए। या संभावित रूप से, ब्राउज़र-आधारित सामान के लिए, कुकी शीर्ष लेख।

आराम

resetpasswordआपके URL जैसे क्रियाकलाप आम तौर पर एक गैर-प्रतिनिधित्व वाले राज्य हस्तांतरण प्रतिमान का एक स्पष्ट संकेत हैं। एक URL को एक संसाधन का प्रतिनिधित्व करना चाहिए। GET का क्या मतलब है resetpassword? या DELETE?

एपीआई

इस योजना के लिए हमेशा पिछला पासवर्ड जानना आवश्यक है। आप शायद अधिक मामलों के लिए अनुमति देना चाहेंगे; जैसे पासवर्ड खो गया है।


आप बेसिक या डाइजेस्ट प्रमाणीकरण का उपयोग कर सकते हैं , जो अच्छी तरह से समझी जाने वाली योजनाएं हैं।

PUT /user/joe/password HTTP/1.0
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Content-Type: text/plain
Host: www.example.com

NEWPASSWD

यह पथ में अति-संवेदनशील जानकारी नहीं डालता है, और यह HTTP और REST सम्मेलनों का अनुसरण करता है।

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


4

सुरक्षा के अलावा, इसके साथ समस्या यह है कि यह बहुत Restful दृष्टिकोण नहीं है।

OLDPASSWDऔर NEWPASSWDआपके संसाधन पदानुक्रम में और भी बदतर के लिए खड़ा नहीं है, ऑपरेशन मूर्खतापूर्ण नहीं है।

तो आप केवल POSTअपने क्रिया के रूप में उपयोग कर सकते हैं , और आपको अपने संसाधन पथ में दो पासवर्ड शामिल नहीं करने चाहिए।


1
आप एक नया रिकॉर्ड नहीं बना रहे हैं, लेकिन एक मौजूदा रिकॉर्ड (आमतौर पर) को अपडेट कर रहे हैं, इसलिए यह POST के बजाय PUT होना चाहिए।

2
@CamilStaps यदि यह केवल पासवर्ड सेट कर रहा था, तो यह हो सकता है। लेकिन संभवत: पुराने पासवर्ड को भी सत्यापित करने की आवश्यकता है, यह ऑपरेशन को गैर-बेरोजगार बनाता है, और इस प्रकार PUTएक क्रिया के रूप में अयोग्य हो जाता है। इसे फिर से काम करने के लिए फिर से तैयार किया जा सकता है, PUTलेकिन इसके मौजूदा स्वरूप में ऐसा नहीं है।
बिज़िकलोप

OLDPASSWD प्रमाणीकरण जानकारी है और URL में बिल्कुल भी नहीं होनी चाहिए।

जरूरी नहीं कि प्रमाणीकरण के शीर्ष पर पुराने पासवर्ड के लिए स्पष्ट रूप से पूछना आम बात है।
biziclop

3

समस्या आपके अनुरोधों में सादे पाठ पासवर्ड से बचने की है। बाकी webservice आवश्यकताओं को पूरा करने के लिए दो विकल्प हैं।

1. ग्राहक पक्ष हैशिंग

  • मुझे लगता है कि आप अपने पासवर्ड स्टोर कर रहे हैं जैसे कि हैश (पासवर्ड + नमक)
  • आप क्लाइंट पासवर्ड पर नमक के साथ नया पासवर्ड रख सकते हैं
  • इसका मतलब है कि: ग्राहक की तरफ एक नया नमक बनाएं, एक हैश बनाएं जैसे हैश (newPassword + newSalt)
  • नए बनाए गए हैश प्लस नमक को अपने बाकी के वेबसर्विस में भेजें
  • पुराने पासवर्ड को हैश के रूप में भी भेजें (OldPassword + oldSalt)

2. एन्क्रिप्शन

  • / Otk / john जैसे उपयोगकर्ता के लिए "वन टाइम की" (otk) संसाधन बनाएँ
  • यह संसाधन एक सुरक्षित रैंडम यूनिक वन टाइम कुंजी देता है, जैसे kbDlJbmNmQ0Y0SmRHZC9GaWtRMW0ycVJpYzhMcVNZTWlMUXV6ZWxLdTZESFRs और एक अद्वितीय ID जैसे कि 9564891515125
  • आपके बाकी वेबसर्विस को इस यादृच्छिक ओटी को अगले सुरक्षित संचार के लिए आईडी 95648915125 के साथ स्टोर करना होगा
  • अपने नए और पुराने पासवर्ड को otk उदा AES के साथ एन्क्रिप्ट करें (सुरक्षा कारणों से आपको पुराने और नए पासवर्ड के लिए दो अलग-अलग ओट का उपयोग करना चाहिए)
  • अपने पासवर्ड पासवर्ड संसाधन में आईडी 95648915125 के साथ एन्क्रिप्टेड पासवर्ड भेजें
  • एक ओट और आईडी संयोजन को केवल एक बार काम करने की अनुमति है, इसलिए आपको पासवर्ड का जप करने के बाद उस संयोजन को हटाना होगा
  • संभावित बेहतर विकल्प: मूल / प्रामाणिक द्वारा वर्तमान / पुराना पासवर्ड भेजें।

नोट: दोनों विकल्पों के लिए HTTPS आवश्यक है!


1
मैं कूटशब्द (OTK और HTTPS के साथ आपका एन्क्रिप्शन स्कीम) पासवर्ड एक्सचेंज को दोहरा क्यों करूँगा? यहाँ हमला वेक्टर क्या है जो HTTPS द्वारा कवर नहीं किया गया है?
बार्ट फ्राइडरिच 14

1
एकमात्र उद्देश्य संभव सर्वर लॉग से बचना है। HTTP अनुरोध बॉडी (उदाहरण के लिए एक प्लेटेक्स्ट नए पासवर्ड के साथ) को भी लॉग किया जा सकता है, हालांकि HTTPS का उपयोग किया जाता है। अन्य संभावित हमला एक स्व-हस्ताक्षरित प्रमाण पत्र का उपयोग है जो विशेष रूप से आंतरिक उद्देश्यों के लिए उपयोग किया जाता है।
maz258

2

पासवर्ड-रीसेट ऑपरेशन की विशेषताएं क्या हैं?

  1. यह कुछ बदलता है।
  2. एक मान है जो इसे सेट किया गया है।
  3. केवल कुछ लोगों को इसे करने की अनुमति है (उपयोगकर्ता, एक व्यवस्थापक, या तो, शायद विभिन्न नियमों के साथ कि या तो ऐसा कैसे कर सकते हैं)।

यहाँ बिंदु 1 का अर्थ है कि आप GET का उपयोग नहीं कर सकते हैं, आपको पासवर्ड बदलने के लिए URI के लिए पासवर्ड-चेंज ऑपरेशन का प्रतिनिधित्व करने के लिए या तो कुछ पोस्ट करना होगा, जो पासवर्ड परिवर्तन को संभालता है, या पासवर्ड का प्रतिनिधित्व करने वाले URI के लिए नए पासवर्ड का प्रतिनिधित्व करने वाली किसी चीज़ को PUT करें या कुछ का प्रतिनिधित्व करें (जैसे उपयोगकर्ता) उस पासवर्ड की एक विशेषता है।

आम तौर पर हम POST करते हैं, कम से कम नहीं क्योंकि यह बहुत अजीब हो सकता है कि हम बाद में कुछ हासिल नहीं कर सकते हैं और निश्चित रूप से हम पासवर्ड प्राप्त नहीं कर सकते हैं।

प्वाइंट 2 इसलिए नए पासवर्ड का प्रतिनिधित्व करने वाला डेटा होगा, जो POSTed है।

प्वाइंट 3 का मतलब है कि हमें अनुरोध को अधिकृत करने की आवश्यकता होगी, जिसका अर्थ है कि यदि उपयोगकर्ता वर्तमान उपयोगकर्ता है तो हमें वर्तमान पासवर्ड की आवश्यकता होगी जो हमें साबित हो (हालांकि जरूरी नहीं कि वर्तमान पासवर्ड प्राप्त हो, जैसे कि हैश-आधारित चुनौती इसका उपयोग बिना भेजे के ज्ञान सिद्ध करने के लिए किया गया था)।

यूआरआई इसलिए की तरह कुछ किया जाना चाहिए <http://example.net/changeCurrentUserPassword>या <http://example.net/users/joe/changePassword>

हम तय कर सकते हैं कि हम POST डेटा के साथ-साथ सामान्य प्राधिकरण तंत्र में वर्तमान पासवर्ड प्राप्त करना चाहते हैं।

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