2008-11-20 24 views
5

मैं एक छोटे से वेब ऐप को एक साथ रख रहा हूं जो डेटाबेस को लिखता है (पर्ल CGI & MySQL)। CGI स्क्रिप्ट किसी फ़ॉर्म से कुछ जानकारी लेती है और इसे डेटाबेस में लिखती है। हालांकि, मुझे लगता है कि अगर मैं वेब ब्राउज़र पर 'रीलोड' या 'बैक' हिट करता हूं, तो यह डाटाबेस को डेटा फिर से लिख देगा। मुझे यह नहीं चाहिए।ब्राउज़र फिर से लोड/बैक करता है जब मैं डेटाबेस को फिर से लिखने से कैसे रोक सकता हूं?

इस मामले में फिर से लिखे गए डेटा के खिलाफ सुरक्षा का सबसे अच्छा तरीका क्या है?

उत्तर

17

संशोधन करने के लिए जीईटी अनुरोधों का उपयोग न करें! RESTful बनें; POST (या PUT) का उपयोग करें, इसके बजाय ब्राउज़र को उपयोगकर्ता को चेतावनी देना चाहिए कि अनुरोध को पुनः लोड न करें। POST/PUT अनुरोध के बाद सामान्य GET अनुरोध का उपयोग करके एक रसीद पृष्ठ पर रीडायरेक्टिंग (using HTTP redirection) पुन: सबमिट करने के बारे में चेतावनी दिए बिना पृष्ठ को रीफ्रेश करना संभव कर देगा।

संपादित करें:

मैं उपयोगकर्ता किसी भी तरह में लॉग ऑन है मान, और इसलिए आप allready, उदा उपयोगकर्ता ट्रैकिंग के कुछ रास्ता है सत्र या इसी तरह के।

आप बना सकते हैं एक टाइमस्टैम्प (या एक यादृच्छिक हैश आदि ..) जब प्रपत्र एक छिपी हुई फ़ील्ड के रूप में यह दोनों भंडारण प्रदर्शित (सिर्फ विरोधी पार साइट अनुरोध टोकन के अलावा मुझे यकीन है कि आप allready वहाँ है हूँ) , और एक सत्र चर (जो आपके सर्वर पर सुरक्षित रूप से संग्रहीत है) में, जब आप इस फ़ॉर्म के लिए POST/PUT अनुरोध प्राप्त करते हैं, तो आप जांचते हैं कि टाइमस्टैम्प सत्र में एक जैसा ही है। यदि ऐसा है, तो आप सत्र में टाइमस्टैम्प को कुछ परिवर्तनीय और अनुमान लगाने में कठोर (उदाहरण के लिए कुछ गुप्त स्ट्रिंग के साथ समेकित टाइमस्टैम्प) सेट करते हैं, तो आप फॉर्म डेटा को सहेज सकते हैं। अगर कोई अनुरोध अब दोहराता है तो आपको सत्र चर में एक ही मूल्य नहीं मिलेगा और अनुरोध को अस्वीकार कर दिया जाएगा।

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

+0

ओपी सिस्टम को गड़बड़ाने वाले अपने उपयोगकर्ताओं के बारे में शिकायत कर रहा है। "अपने ब्राउजर को कोशिश करने और रोकने के लिए" कहें, समस्या के लिए शायद ही कभी कास्ट आयरन समाधान है। –

+2

नहीं, लेकिन यह सौम्य उपयोगकर्ताओं को ऐसा करने की संभावना कम करता है, मैंने समस्या को और कम करने के लिए कुछ विचार जोड़े। –

4

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

बस मेरे 2 सेंट।

6

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

1

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

+0

आप टिकट नंबर जारी करते हैं, फिर केवल टिकट को एक बार पंच करें। – dkretz

1

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

और ठीक है तो: यदि आप डुप्लिकेट सबमिशन नहीं चाहते हैं, तो उपयोगकर्ता की नहीं, हल करने में आपकी समस्या है।

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

1

I ब्राउज़र से पोस्ट चेतावनियों पर भरोसा नहीं है। संदेश संदेशों को दूर करने के लिए उपयोगकर्ता बस ठीक क्लिक करें।

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

(बारी-बारी से टोकन कि वापस आ गए हैं पर नज़र रखने, और यदि आप इसे फिर से पहले प्राप्त हुआ है यह अवैध है।)

+0

हालांकि, दौड़ की स्थिति के साथ अभी भी कोई समस्या है। जैसे ही आपको टोकन प्राप्त होता है, आपको यह जांचना होगा कि इसका पहले से उपयोग नहीं किया गया है, उदा। एक SQL अद्यतन कमांड जारी करें, और जांचें कि वापसी मान 1 है (आपने कुछ बदल दिया है) या 0E0 (आपने इसे पहले से ही बदलने की कोशिश की है)। –

0

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

संबंधित मुद्दे