रक्षात्मक प्रोग्रामिंग

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

रक्षात्मक प्रोग्रामिंग सॉफ़्टवेयर और स्रोत कोड को बेहतर बनाने के लिए एक दृष्टिकोण है, के संदर्भ में:


 * सामान्य गुणवत्ता - सॉफ्टवेयर बग और समस्याओं की संख्या को कम करना है।
 * स्रोत कोड को समझ में आता है - स्रोत कोड पठनीय और समझ में आता है इसलिए इसे कोड ऑडिट में अनुमोदित किया जाता है।
 * अप्रत्याशित इनपुट या उपयोगकर्ता कार्यों के बावजूद सॉफ़्टवेयर को एक अनुमानित तरीके से व्यवहार करना है।

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

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

फ़ंक्शन को अपरिभाषित व्यवहार में परिणाम होगा जब इनपुट 1000 से अधिक वर्णों का है। कुछ प्रोग्रामर यह महसूस नहीं कर सकते हैं कि यह एक समस्या है, यह मानते हुए कि कोई भी उपयोगकर्ता इतने लंबे इनपुट में प्रवेश नहीं करेगा। यह विशेष बग एक भेद्यता को प्रदर्शित करता है जो बफर ओवरफ्लो एक्सप्लॉइट्स को सक्षम करता है। यहाँ इस उदाहरण का समाधान है:

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

आंतरिक डेटा वैधता पर विश्वास करना
अत्यधिक रक्षात्मक प्रोग्रामिंग

ओफ्फेंसिव प्रोग्रामिंग

सॉफ्टवेयर घटकों पर विश्वास करना
अत्यधिक रक्षात्मक प्रोग्रामिंग if (is_legacy_compatible(user_config)) { // Strategy: Don't trust that the new code behaves the same old_code(user_config); } else { // Fallback: Don't trust that the new code handles the same cases if (new_code(user_config)n!= OK) { old_code(user_config); } } आक्रामक प्रोग्रामिंग // Expect that the new code has no new bugs if (new_code(user_config))!= OK) { // Loudly report and abruptly terminate program to get proper attention  report_error("Something went very wrong");  exit(-1); }

तकनीक
यहाँ कुछ रक्षात्मक प्रोग्रामिंग तकनीकें हैं:

इंटेलिजेंट सोर्स कोड का पुन: उपयोग
यदि मौजूदा कोड का परीक्षण किया गया है और काम करने के लिए जाना जाता है, तो इसका पुन: उपयोग करने से बग्स के पेश होने की संभावना कम हो सकती है।

हालाँकि, कोड का पुन: उपयोग करना हमेशा अच्छा अभ्यास नहीं होता है। मौजूदा कोड का पुन: उपयोग, विशेष रूप से जब व्यापक रूप से वितरित किया जाता है, ऐसे शोषण के लिए अनुमति दे सकता है जो अन्यथा संभव से अधिक व्यापक दर्शकों को लक्षित करता है और पुन: उपयोग किए गए कोड की सभी सुरक्षा और कमजोरियों को अपने साथ लाता है।

मौजूदा स्रोत कोड का उपयोग करने पर विचार करते समय, मॉड्यूल की त्वरित समीक्षा (वर्ग या कार्यों जैसे उप-वर्ग) डेवलपर को किसी भी संभावित कमजोरियों से अवगत कराने या जागरूक करने में मदद करेगा और यह सुनिश्चित करेगा कि यह परियोजना में उपयोग करने के लिए उपयुक्त है।

लिगेसी समस्याएं
पुराने स्रोत कोड, पुस्तकालयों, एपीआई, कॉन्फ़िगरेशन आदि का पुन: उपयोग करने से पहले, यह विचार किया जाना चाहिए कि क्या पुराना कार्य पुन: उपयोग के लिए मान्य है, या यदि यह विरासत प्रणाली की समस्याओं से ग्रस्त होने की संभावना है।

विरासत की समस्याएं अंतर्निहित समस्याएं हैं जब पुराने डिजाइनों से आज की आवश्यकताओं के साथ काम करने की उम्मीद की जाती है, खासकर जब पुराने डिजाइनों को उन आवश्यकताओं को ध्यान में रखते हुए विकसित या परीक्षण नहीं किया गया था।

कई सॉफ्टवेयर उत्पादों में पुराने विरासत स्रोत कोड के साथ समस्याओं का अनुभव हुआ है; उदाहरण के लिए:
 * लीगेसी कोड एक रक्षात्मक प्रोग्रामिंग पहल के तहत डिज़ाइन नहीं किया गया हो सकता है, और इसलिए नए डिज़ाइन किए गए स्रोत कोड की तुलना में बहुत कम गुणवत्ता वाला हो सकता है।
 * लीगेसी कोड को उन शर्तों के तहत लिखा और परखा जा सकता है जो अब लागू नहीं होती हैं। पुराने गुणवत्ता आश्वासन परीक्षणों की अब कोई वैधता नहीं हो सकती है।
 * उदाहरण 1: पुराने कोड को एएससीआईआई इनपुट के लिए डिज़ाइन किया गया हो सकता है लेकिन अब इनपुट यूटीएफ-8 है।
 * उदाहरण 2: 32-बिट आर्किटेक्चर पर लीगेसी कोड संकलित और परीक्षण किया जा सकता है, लेकिन जब 64-बिट आर्किटेक्चर पर संकलित किया जाता है, तो नई अंकगणितीय समस्याएं हो सकती हैं (जैसे, अमान्य हस्ताक्षर परीक्षण, अमान्य टाइप कास्ट, आदि)।
 * उदाहरण 3: लीगेसी कोड को ऑफ़लाइन मशीनों के लिए लक्षित किया जा सकता है, लेकिन नेटवर्क कनेक्टिविटी जुड़ जाने के बाद यह असुरक्षित हो जाता है।
 * लिगेसी कोड नई समस्याओं को ध्यान में रखकर नहीं लिखा गया है। उदाहरण के लिए, 1990 में लिखे गए स्रोत कोड में कई कोड इंजेक्शन भेद्यता होने की संभावना है, क्योंकि उस समय ऐसी अधिकांश समस्याओं को व्यापक रूप से समझा नहीं गया था।

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

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

"संभावित" बग के प्रति कम सहिष्णुता
मान लें कि कोड निर्माण जो समस्या प्रवण प्रतीत होते हैं (ज्ञात कमजोरियों के समान, आदि) बग और संभावित सुरक्षा दोष हैं। बुनियादी नियम यह है: मुझे सभी प्रकार के सुरक्षा कारनामों की जानकारी नहीं है। मुझे उन लोगों से बचाव करना चाहिए जिनके बारे में मैं जानता हूं और फिर मुझे सक्रिय होना चाहिए ! .

अपना कोड सुरक्षित करने के लिए और टिप्स

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

डेटा सुरक्षा के 3 कानून
* अन्यथा सिद्ध होने तक सभी डेटा महत्वपूर्ण हैं। * अन्यथा सिद्ध होने तक सभी डेटा दूषित हैं। * अन्यथा साबित होने तक सभी कोड असुरक्षित हैं।

डेटा सुरक्षा के बारे में ये तीन नियम बताते हैं कि आंतरिक या बाह्य रूप से किसी भी डेटा को कैसे संभालना है:
 * आप यूजरलैंड में किसी भी कोड की सुरक्षा को साबित नहीं कर सकते, या, जिसे आमतौर पर "क्लाइंट पर कभी भरोसा नहीं" के रूप में जाना जाता है।

 'अन्यथा सिद्ध होने तक सभी डेटा महत्वपूर्ण हैं' - इसका अर्थ है कि नष्ट होने से पहले सभी डेटा को कचरा के रूप में सत्यापित किया जाना चाहिए।

 'अन्यथा सिद्ध होने तक सभी डेटा दागी हैं' - इसका मतलब है कि सभी डेटा को इस तरह से संभाला जाना चाहिए जो अखंडता को सत्यापित किए बिना शेष रनटाइम वातावरण को उजागर न करे।

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

अधिक जानकारी

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

यह भी देखें

 * कंप्यूटर सुरक्षा
 * प्रतिरक्षा-जागरूक प्रोग्रामिंग

बाहरी संबंध

 * CERT Secure Coding Standards