स्मार्ट अनुबंध सुरक्षा
स्मार्ट अनुबंध अत्यंत लचीले होते हैं, और ब्लॉकचेन पर तैनात कोड के आधार पर अपरिवर्तनीय लॉजिक चलाते हुए बड़ी मात्रा में मूल्य और डेटा को नियंत्रित करने में सक्षम होते हैं। इसने विश्वासहीन और विकेंद्रीकृत एप्लिकेशन का एक जीवंत इकोसिस्टम बनाया है जो पुराने सिस्टम की तुलना में कई लाभ प्रदान करते हैं। वे स्मार्ट अनुबंधों में कमजोरियों का फायदा उठाकर लाभ कमाने की चाह रखने वाले हमलावरों के लिए अवसर भी प्रस्तुत करते हैं।
सार्वजनिक ब्लॉकचेन, जैसे इथेरियम, स्मार्ट अनुबंधों को सुरक्षित करने के मुद्दे को और जटिल बनाते हैं। तैनात किए गए अनुबंध कोड को आमतौर पर सुरक्षा खामियों को ठीक करने के लिए बदला नहीं जा सकता है, जबकि स्मार्ट अनुबंधों से चुराई गई संपत्तियों को ट्रैक करना बेहद मुश्किल होता है और अपरिवर्तनीयता के कारण ज्यादातर अप्राप्य होती हैं।
हालांकि आंकड़े अलग-अलग हैं, यह अनुमान लगाया गया है कि स्मार्ट अनुबंधों में सुरक्षा दोषों के कारण चुराए गए या खोए गए मूल्य की कुल राशि आसानी से $1 बिलियन से अधिक है। इसमें हाई-प्रोफाइल घटनाएं शामिल हैं, जैसे कि विकेंद्रीकृत स्वायत्त संगठन (DAO) हैक (नए टैब में खुलता है) (3.6M ETH चुराए गए, जिनकी आज की कीमत $1B से अधिक है), Parity बहु-हस्ताक्षर वॉलेट हैक (नए टैब में खुलता है) (हैकर्स द्वारा $30M का नुकसान), और Parity फ्रोजन वॉलेट समस्या (नए टैब में खुलता है) (हमेशा के लिए लॉक किए गए $300M से अधिक के ETH)।
उपर्युक्त मुद्दे डेवलपर्स के लिए सुरक्षित, मजबूत और प्रतिरोधी स्मार्ट अनुबंध बनाने में प्रयास करना अनिवार्य बनाते हैं। स्मार्ट अनुबंध सुरक्षा एक गंभीर विषय है, और इसे सीखना हर डेवलपर के लिए फायदेमंद होगा। यह गाइड इथेरियम डेवलपर्स के लिए सुरक्षा संबंधी विचारों को कवर करेगी और स्मार्ट अनुबंध सुरक्षा में सुधार के लिए संसाधनों का पता लगाएगी।
पूर्वापेक्षाएँ
सुरक्षा पर काम करने से पहले सुनिश्चित करें कि आप स्मार्ट अनुबंध विकास के मूल सिद्धांतों से परिचित हैं।
सुरक्षित इथेरियम स्मार्ट अनुबंध बनाने के लिए दिशानिर्देश
1. उचित एक्सेस कंट्रोल डिज़ाइन करें
स्मार्ट अनुबंध में, public या external के रूप में चिह्नित फ़ंक्शंस को किसी भी बाह्य स्वामित्व वाले खाते (EOA) या अनुबंध खातों द्वारा कॉल किया जा सकता है। यदि आप चाहते हैं कि अन्य लोग आपके अनुबंध के साथ इंटरैक्ट करें, तो फ़ंक्शंस के लिए सार्वजनिक दृश्यता (public visibility) निर्दिष्ट करना आवश्यक है। हालाँकि, private के रूप में चिह्नित फ़ंक्शंस को केवल स्मार्ट अनुबंध के भीतर के फ़ंक्शंस द्वारा ही कॉल किया जा सकता है, बाहरी खातों द्वारा नहीं। प्रत्येक नेटवर्क प्रतिभागी को अनुबंध फ़ंक्शंस तक पहुंच देने से समस्याएँ हो सकती हैं, खासकर यदि इसका मतलब है कि कोई भी संवेदनशील संचालन (जैसे, नए टोकन की मिंटिंग) कर सकता है।
स्मार्ट अनुबंध फ़ंक्शंस के अनधिकृत उपयोग को रोकने के लिए, सुरक्षित एक्सेस कंट्रोल लागू करना आवश्यक है। एक्सेस कंट्रोल तंत्र स्मार्ट अनुबंध में कुछ फ़ंक्शंस का उपयोग करने की क्षमता को स्वीकृत संस्थाओं तक सीमित करते हैं, जैसे कि अनुबंध के प्रबंधन के लिए जिम्मेदार खाते। Ownable पैटर्न और भूमिका-आधारित नियंत्रण (role-based control) स्मार्ट अनुबंध में एक्सेस कंट्रोल लागू करने के लिए उपयोगी दो पैटर्न हैं:
Ownable पैटर्न
Ownable पैटर्न में, अनुबंध-निर्माण प्रक्रिया के दौरान एक पते को अनुबंध के "मालिक (owner)" के रूप में सेट किया जाता है। संरक्षित फ़ंक्शंस को एक OnlyOwner संशोधक (modifier) सौंपा जाता है, जो यह सुनिश्चित करता है कि अनुबंध फ़ंक्शन को निष्पादित करने से पहले कॉल करने वाले पते की पहचान को प्रमाणित करता है। अनुबंध के मालिक के अलावा अन्य पतों से संरक्षित फ़ंक्शंस पर कॉल हमेशा रिवर्ट हो जाती हैं, जिससे अवांछित पहुंच को रोका जा सकता है।
भूमिका-आधारित एक्सेस कंट्रोल
स्मार्ट अनुबंध में एक ही पते को Owner के रूप में पंजीकृत करने से केंद्रीकरण का जोखिम पैदा होता है और यह विफलता के एकल बिंदु (single point-of-failure) का प्रतिनिधित्व करता है। यदि मालिक के खाते की कुंजियों (keys) से समझौता किया जाता है, तो हमलावर स्वामित्व वाले अनुबंध पर हमला कर सकते हैं। यही कारण है कि कई प्रशासनिक खातों के साथ भूमिका-आधारित एक्सेस कंट्रोल पैटर्न का उपयोग करना एक बेहतर विकल्प हो सकता है।
भूमिका-आधारित एक्सेस कंट्रोल में, संवेदनशील फ़ंक्शंस तक पहुंच विश्वसनीय प्रतिभागियों के एक समूह के बीच वितरित की जाती है। उदाहरण के लिए, एक खाता टोकन की मिंटिंग के लिए जिम्मेदार हो सकता है, जबकि दूसरा खाता अपग्रेड करता है या अनुबंध को रोकता (pause) है। इस तरह एक्सेस कंट्रोल को विकेंद्रीकृत करने से विफलता के एकल बिंदु समाप्त हो जाते हैं और उपयोगकर्ताओं के लिए विश्वास मान्यताएँ कम हो जाती हैं।
बहु-हस्ताक्षर वॉलेट का उपयोग करना
सुरक्षित एक्सेस कंट्रोल लागू करने का एक अन्य दृष्टिकोण अनुबंध का प्रबंधन करने के लिए बहु-हस्ताक्षर खाते का उपयोग करना है। एक नियमित EOA के विपरीत, बहु-हस्ताक्षर खातों का स्वामित्व कई संस्थाओं के पास होता है और लेन-देन निष्पादित करने के लिए न्यूनतम संख्या में खातों—मान लीजिए 5 में से 3—से हस्ताक्षर की आवश्यकता होती है।
एक्सेस कंट्रोल के लिए मल्टीसिग का उपयोग करने से सुरक्षा की एक अतिरिक्त परत जुड़ जाती है क्योंकि लक्ष्य अनुबंध पर कार्रवाई के लिए कई पक्षों की सहमति की आवश्यकता होती है। यह विशेष रूप से उपयोगी है यदि Ownable पैटर्न का उपयोग करना आवश्यक है, क्योंकि यह किसी हमलावर या दुष्ट अंदरूनी सूत्र के लिए दुर्भावनापूर्ण उद्देश्यों के लिए संवेदनशील अनुबंध फ़ंक्शंस में हेरफेर करना अधिक कठिन बना देता है।
2. अनुबंध संचालन की सुरक्षा के लिए require(), assert(), और revert() कथनों का उपयोग करें
जैसा कि उल्लेख किया गया है, एक बार ब्लॉकचेन पर तैनात होने के बाद कोई भी आपके स्मार्ट अनुबंध में सार्वजनिक फ़ंक्शंस को कॉल कर सकता है। चूंकि आप पहले से नहीं जान सकते कि बाहरी खाते अनुबंध के साथ कैसे इंटरैक्ट करेंगे, इसलिए तैनाती से पहले समस्याग्रस्त संचालन के खिलाफ आंतरिक सुरक्षा उपाय लागू करना आदर्श है। यदि निष्पादन कुछ आवश्यकताओं को पूरा करने में विफल रहता है, तो आप अपवादों (exceptions) को ट्रिगर करने और स्थिति परिवर्तनों को रिवर्ट करने के लिए require(), assert(), और revert() कथनों का उपयोग करके स्मार्ट अनुबंध में सही व्यवहार लागू कर सकते हैं।
require(): require को फ़ंक्शंस की शुरुआत में परिभाषित किया जाता है और यह सुनिश्चित करता है कि कॉल किए गए फ़ंक्शन को निष्पादित करने से पहले पूर्व-निर्धारित शर्तें पूरी हों। एक require कथन का उपयोग उपयोगकर्ता इनपुट को मान्य करने, स्थिति चर (state variables) की जांच करने, या किसी फ़ंक्शन के साथ आगे बढ़ने से पहले कॉल करने वाले खाते की पहचान को प्रमाणित करने के लिए किया जा सकता है।
assert(): assert() का उपयोग आंतरिक त्रुटियों का पता लगाने और आपके कोड में "इनवेरिएंट्स (invariants)" के उल्लंघन की जांच करने के लिए किया जाता है। एक इनवेरिएंट अनुबंध की स्थिति के बारे में एक तार्किक दावा है जो सभी फ़ंक्शन निष्पादन के लिए सत्य होना चाहिए। एक उदाहरण इनवेरिएंट किसी टोकन अनुबंध की अधिकतम कुल आपूर्ति या शेष राशि है। assert() का उपयोग यह सुनिश्चित करता है कि आपका अनुबंध कभी भी कमजोर स्थिति में न पहुंचे, और यदि ऐसा होता है, तो स्थिति चर में सभी परिवर्तन वापस (roll back) ले लिए जाते हैं।
revert(): revert() का उपयोग if-else कथन में किया जा सकता है जो आवश्यक शर्त पूरी न होने पर अपवाद को ट्रिगर करता है। नीचे दिया गया नमूना अनुबंध फ़ंक्शंस के निष्पादन की सुरक्षा के लिए revert() का उपयोग करता है:
pragma solidity ^0.8.4;
contract VendingMachine {
address owner;
error Unauthorized();
function buy(uint amount) public payable {
if (amount > msg.value / 2 ether)
revert("Not enough Ether provided.");
// खरीदारी करें।
}
function withdraw() public {
if (msg.sender != owner)
revert Unauthorized();
payable(msg.sender).transfer(address(this).balance);
}
}
3. स्मार्ट अनुबंध का परीक्षण करें और कोड की शुद्धता सत्यापित करें
इथेरियम वर्चुअल मशीन (EVM) में चलने वाले कोड की अपरिवर्तनीयता का मतलब है कि स्मार्ट अनुबंध विकास चरण के दौरान उच्च स्तर के गुणवत्ता मूल्यांकन की मांग करते हैं। अपने अनुबंध का बड़े पैमाने पर परीक्षण करना और किसी भी अप्रत्याशित परिणाम के लिए इसका अवलोकन करना सुरक्षा में काफी सुधार करेगा और लंबे समय में आपके उपयोगकर्ताओं की रक्षा करेगा।
सामान्य तरीका मॉक डेटा का उपयोग करके छोटे यूनिट परीक्षण लिखना है जो अनुबंध को उपयोगकर्ताओं से प्राप्त होने की उम्मीद है। यूनिट परीक्षण कुछ फ़ंक्शंस की कार्यक्षमता का परीक्षण करने और यह सुनिश्चित करने के लिए अच्छा है कि एक स्मार्ट अनुबंध अपेक्षा के अनुरूप काम करता है।
दुर्भाग्य से, जब अलगाव में उपयोग किया जाता है तो स्मार्ट अनुबंध सुरक्षा में सुधार के लिए यूनिट परीक्षण न्यूनतम रूप से प्रभावी होता है। एक यूनिट परीक्षण यह साबित कर सकता है कि एक फ़ंक्शन मॉक डेटा के लिए ठीक से निष्पादित होता है, लेकिन यूनिट परीक्षण केवल उतने ही प्रभावी होते हैं जितने कि लिखे गए परीक्षण। इससे छूटे हुए एज केस और कमजोरियों का पता लगाना मुश्किल हो जाता है जो आपके स्मार्ट अनुबंध की सुरक्षा को तोड़ सकते हैं।
एक बेहतर दृष्टिकोण यूनिट परीक्षण को स्थैतिक और गतिशील विश्लेषण (static and dynamic analysis) का उपयोग करके किए गए संपत्ति-आधारित परीक्षण (property-based testing) के साथ जोड़ना है। स्थैतिक विश्लेषण पहुंच योग्य प्रोग्राम स्थितियों और निष्पादन पथों का विश्लेषण करने के लिए निम्न-स्तरीय अभ्यावेदन, जैसे नियंत्रण प्रवाह ग्राफ़ (control flow graphs) (नए टैब में खुलता है) और अमूर्त सिंटैक्स ट्री (abstract syntax trees) (नए टैब में खुलता है) पर निर्भर करता है। इस बीच, गतिशील विश्लेषण तकनीकें, जैसे स्मार्ट अनुबंध फ़ज़िंग (नए टैब में खुलता है), सुरक्षा गुणों का उल्लंघन करने वाले संचालन का पता लगाने के लिए यादृच्छिक इनपुट मानों के साथ अनुबंध कोड निष्पादित करती हैं।
औपचारिक सत्यापन स्मार्ट अनुबंध में सुरक्षा गुणों को सत्यापित करने की एक और तकनीक है। नियमित परीक्षण के विपरीत, औपचारिक सत्यापन निर्णायक रूप से स्मार्ट अनुबंध में त्रुटियों की अनुपस्थिति को साबित कर सकता है। यह एक औपचारिक विनिर्देश बनाकर प्राप्त किया जाता है जो वांछित सुरक्षा गुणों को कैप्चर करता है और यह साबित करता है कि अनुबंध का एक औपचारिक मॉडल इस विनिर्देश का पालन करता है।
4. अपने कोड की स्वतंत्र समीक्षा के लिए पूछें
अपने अनुबंध का परीक्षण करने के बाद, दूसरों से किसी भी सुरक्षा समस्या के लिए स्रोत कोड की जांच करने के लिए कहना अच्छा है। परीक्षण एक स्मार्ट अनुबंध में हर खामी को उजागर नहीं करेगा, लेकिन एक स्वतंत्र समीक्षा प्राप्त करने से कमजोरियों को पहचानने की संभावना बढ़ जाती है।
ऑडिट
स्मार्ट अनुबंध ऑडिट शुरू करना एक स्वतंत्र कोड समीक्षा आयोजित करने का एक तरीका है। ऑडिटर यह सुनिश्चित करने में महत्वपूर्ण भूमिका निभाते हैं कि स्मार्ट अनुबंध सुरक्षित हैं और गुणवत्ता दोषों और डिज़ाइन त्रुटियों से मुक्त हैं।
इसके बावजूद, आपको ऑडिट को रामबाण (silver bullet) मानने से बचना चाहिए। स्मार्ट अनुबंध ऑडिट हर बग को नहीं पकड़ेंगे और ज्यादातर समीक्षाओं का एक अतिरिक्त दौर प्रदान करने के लिए डिज़ाइन किए गए हैं, जो प्रारंभिक विकास और परीक्षण के दौरान डेवलपर्स द्वारा छूटे गए मुद्दों का पता लगाने में मदद कर सकते हैं। स्मार्ट अनुबंध ऑडिट के लाभ को अधिकतम करने के लिए आपको ऑडिटर्स के साथ काम करने के लिए सर्वोत्तम प्रथाओं का भी पालन करना चाहिए, जैसे कोड का ठीक से दस्तावेजीकरण करना और इनलाइन टिप्पणियां जोड़ना।
- स्मार्ट अनुबंध ऑडिटिंग टिप्स और ट्रिक्स (नए टैब में खुलता है) - @tinchoabbate
- अपने ऑडिट का अधिकतम लाभ उठाएं (नए टैब में खुलता है) - Inference
बग बाउंटी
बग बाउंटी प्रोग्राम स्थापित करना बाहरी कोड समीक्षाओं को लागू करने का एक और दृष्टिकोण है। बग बाउंटी एक वित्तीय पुरस्कार है जो उन व्यक्तियों (आमतौर पर व्हाइटहैट हैकर्स) को दिया जाता है जो किसी एप्लिकेशन में कमजोरियों की खोज करते हैं।
जब ठीक से उपयोग किया जाता है, तो बग बाउंटी हैकर समुदाय के सदस्यों को महत्वपूर्ण खामियों के लिए आपके कोड का निरीक्षण करने के लिए प्रोत्साहन देती है। एक वास्तविक जीवन का उदाहरण "अनंत धन बग (infinite money bug)" है जो एक हमलावर को इथेरियम पर चलने वाले लेयर 2 (L2) प्रोटोकॉल, ऑप्टिमिज़्म (नए टैब में खुलता है) पर असीमित मात्रा में ईथर बनाने देता। सौभाग्य से, एक व्हाइटहैट हैकर ने खामी की खोज की (नए टैब में खुलता है) और टीम को सूचित किया, इस प्रक्रिया में एक बड़ा भुगतान अर्जित किया (नए टैब में खुलता है)।
एक उपयोगी रणनीति दांव पर लगे धन की मात्रा के अनुपात में बग बाउंटी प्रोग्राम का भुगतान निर्धारित करना है। "स्केलिंग बग बाउंटी (नए टैब में खुलता है)" के रूप में वर्णित, यह दृष्टिकोण व्यक्तियों को कमजोरियों का फायदा उठाने के बजाय जिम्मेदारी से उनका खुलासा करने के लिए वित्तीय प्रोत्साहन प्रदान करता है।
5. स्मार्ट अनुबंध विकास के दौरान सर्वोत्तम प्रथाओं का पालन करें
ऑडिट और बग बाउंटी का अस्तित्व आपको उच्च-गुणवत्ता वाला कोड लिखने की आपकी जिम्मेदारी से मुक्त नहीं करता है। अच्छी स्मार्ट अनुबंध सुरक्षा उचित डिज़ाइन और विकास प्रक्रियाओं का पालन करने से शुरू होती है:
-
सभी कोड को संस्करण नियंत्रण प्रणाली (version control system), जैसे git में स्टोर करें
-
पुल अनुरोधों (pull requests) के माध्यम से सभी कोड संशोधन करें
-
सुनिश्चित करें कि पुल अनुरोधों में कम से कम एक स्वतंत्र समीक्षक हो—यदि आप किसी प्रोजेक्ट पर अकेले काम कर रहे हैं, तो अन्य डेवलपर्स को खोजने और कोड समीक्षाओं का व्यापार करने पर विचार करें
-
स्मार्ट अनुबंध के परीक्षण, संकलन, और तैनाती के लिए एक विकास वातावरण (development environment) का उपयोग करें
-
अपने कोड को बुनियादी कोड विश्लेषण टूल, जैसे Cyfrin Aderyn (नए टैब में खुलता है), Mythril और स्लिथर के माध्यम से चलाएं। आदर्श रूप से, आपको प्रत्येक पुल अनुरोध के मर्ज होने से पहले ऐसा करना चाहिए और आउटपुट में अंतर की तुलना करनी चाहिए
-
सुनिश्चित करें कि आपका कोड बिना किसी त्रुटि के संकलित होता है, और Solidity कंपाइलर कोई चेतावनी नहीं देता है
-
अपने कोड का ठीक से दस्तावेजीकरण करें (NatSpec (नए टैब में खुलता है) का उपयोग करके) और अनुबंध आर्किटेक्चर के बारे में विवरण आसानी से समझ में आने वाली भाषा में वर्णित करें। इससे दूसरों के लिए आपके कोड का ऑडिट और समीक्षा करना आसान हो जाएगा।
6. मजबूत आपदा रिकवरी योजनाएं लागू करें
सुरक्षित एक्सेस कंट्रोल डिज़ाइन करना, फ़ंक्शन संशोधक लागू करना, और अन्य सुझाव स्मार्ट अनुबंध सुरक्षा में सुधार कर सकते हैं, लेकिन वे दुर्भावनापूर्ण कारनामों की संभावना से इंकार नहीं कर सकते हैं। सुरक्षित स्मार्ट अनुबंध बनाने के लिए "विफलता की तैयारी" और हमलों का प्रभावी ढंग से जवाब देने के लिए एक फ़ॉलबैक योजना की आवश्यकता होती है। एक उचित आपदा रिकवरी योजना में निम्नलिखित में से कुछ या सभी घटक शामिल होंगे:
अनुबंध अपग्रेड
जबकि इथेरियम स्मार्ट अनुबंध डिफ़ॉल्ट रूप से अपरिवर्तनीय होते हैं, अपग्रेड पैटर्न का उपयोग करके कुछ हद तक परिवर्तनशीलता प्राप्त करना संभव है। उन मामलों में अनुबंध को अपग्रेड करना आवश्यक है जहां एक महत्वपूर्ण खामी आपके पुराने अनुबंध को अनुपयोगी बना देती है और नया लॉजिक तैनात करना सबसे व्यवहार्य विकल्प है।
अनुबंध अपग्रेड तंत्र अलग तरह से काम करते हैं, लेकिन "प्रॉक्सी पैटर्न" स्मार्ट अनुबंध को अपग्रेड करने के लिए अधिक लोकप्रिय दृष्टिकोणों में से एक है। प्रॉक्सी पैटर्न (नए टैब में खुलता है) किसी एप्लिकेशन की स्थिति और लॉजिक को दो अनुबंध के बीच विभाजित करते हैं। पहला अनुबंध (जिसे 'प्रॉक्सी अनुबंध' कहा जाता है) स्थिति चर (जैसे, उपयोगकर्ता शेष) संग्रहीत करता है, जबकि दूसरा अनुबंध (जिसे 'लॉजिक अनुबंध' कहा जाता है) अनुबंध फ़ंक्शंस को निष्पादित करने के लिए कोड रखता है।
खाते प्रॉक्सी अनुबंध के साथ इंटरैक्ट करते हैं, जो delegatecall() (नए टैब में खुलता है) निम्न-स्तरीय कॉल का उपयोग करके सभी फ़ंक्शन कॉल को लॉजिक अनुबंध में भेजता है। एक नियमित संदेश कॉल के विपरीत, delegatecall() यह सुनिश्चित करता है कि लॉजिक अनुबंध के पते पर चलने वाला कोड कॉलिंग अनुबंध के संदर्भ में निष्पादित हो। इसका मतलब है कि लॉजिक अनुबंध हमेशा प्रॉक्सी के स्टोरेज (अपने स्वयं के स्टोरेज के बजाय) में लिखेगा और msg.sender और msg.value के मूल मान संरक्षित रहेंगे।
लॉजिक अनुबंध को कॉल सौंपने के लिए इसके पते को प्रॉक्सी अनुबंध के स्टोरेज में संग्रहीत करने की आवश्यकता होती है। इसलिए, अनुबंध के लॉजिक को अपग्रेड करना केवल एक और लॉजिक अनुबंध तैनात करने और प्रॉक्सी अनुबंध में नया पता संग्रहीत करने का मामला है। चूंकि प्रॉक्सी अनुबंध के बाद के कॉल स्वचालित रूप से नए लॉजिक अनुबंध में रूट किए जाते हैं, इसलिए आपने वास्तव में कोड को संशोधित किए बिना अनुबंध को "अपग्रेड" कर लिया होगा।
अनुबंध अपग्रेड करने के बारे में अधिक जानकारी।
आपातकालीन रोक (Emergency stops)
जैसा कि उल्लेख किया गया है, व्यापक ऑडिटिंग और परीक्षण संभवतः एक स्मार्ट अनुबंध में सभी बग की खोज नहीं कर सकते हैं। यदि तैनाती के बाद आपके कोड में कोई भेद्यता दिखाई देती है, तो इसे पैच करना असंभव है क्योंकि आप अनुबंध पते पर चलने वाले कोड को नहीं बदल सकते हैं। इसके अलावा, अपग्रेड तंत्र (जैसे, प्रॉक्सी पैटर्न) को लागू करने में समय लग सकता है (उन्हें अक्सर विभिन्न पक्षों से अनुमोदन की आवश्यकता होती है), जो केवल हमलावरों को अधिक नुकसान पहुंचाने के लिए अधिक समय देता है।
अंतिम विकल्प (nuclear option) एक "आपातकालीन रोक" फ़ंक्शन को लागू करना है जो अनुबंध में कमजोर फ़ंक्शंस के कॉल को ब्लॉक करता है। आपातकालीन रोक में आमतौर पर निम्नलिखित घटक शामिल होते हैं:
-
एक वैश्विक बूलियन चर जो यह दर्शाता है कि स्मार्ट अनुबंध रुकी हुई स्थिति में है या नहीं। अनुबंध सेट करते समय यह चर
falseपर सेट होता है, लेकिन अनुबंध बंद होने के बाद यहtrueपर वापस आ जाएगा। -
फ़ंक्शंस जो अपने निष्पादन में बूलियन चर को संदर्भित करते हैं। ऐसे फ़ंक्शंस तब सुलभ होते हैं जब स्मार्ट अनुबंध बंद नहीं होता है, और आपातकालीन रोक सुविधा चालू होने पर दुर्गम हो जाते हैं।
-
एक इकाई जिसकी आपातकालीन रोक फ़ंक्शन तक पहुंच है, जो बूलियन चर को
trueपर सेट करती है। दुर्भावनापूर्ण कार्यों को रोकने के लिए, इस फ़ंक्शन के कॉल को एक विश्वसनीय पते (जैसे, अनुबंध के मालिक) तक सीमित किया जा सकता है।
एक बार जब अनुबंध आपातकालीन रोक को सक्रिय कर देता है, तो कुछ फ़ंक्शंस कॉल करने योग्य नहीं होंगे। यह चुनिंदा फ़ंक्शंस को एक संशोधक में लपेटकर प्राप्त किया जाता है जो वैश्विक चर को संदर्भित करता है। नीचे एक उदाहरण (नए टैब में खुलता है) दिया गया है जो अनुबंध में इस पैटर्न के कार्यान्वयन का वर्णन करता है:
// इस कोड का पेशेवर रूप से ऑडिट नहीं किया गया है और यह सुरक्षा या शुद्धता के बारे में कोई वादा नहीं करता है। अपने जोखिम पर उपयोग करें।
contract EmergencyStop {
bool isStopped = false;
modifier stoppedInEmergency {
require(!isStopped);
_;
}
modifier onlyWhenStopped {
require(isStopped);
_;
}
modifier onlyAuthorized {
// यहाँ msg.sender के प्राधिकरण की जाँच करें
_;
}
function stopContract() public onlyAuthorized {
isStopped = true;
}
function resumeContract() public onlyAuthorized {
isStopped = false;
}
function deposit() public payable stoppedInEmergency {
// जमा करने का लॉजिक यहाँ हो रहा है
}
function emergencyWithdraw() public onlyWhenStopped {
// आपातकालीन निकासी यहाँ हो रही है
}
}
यह उदाहरण आपातकालीन रोक की बुनियादी विशेषताएं दिखाता है:
-
isStoppedएक बूलियन है जो शुरुआत मेंfalseऔर अनुबंध के आपातकालीन मोड में प्रवेश करने परtrueका मूल्यांकन करता है। -
फ़ंक्शन संशोधक
onlyWhenStoppedऔरstoppedInEmergencyisStoppedचर की जांच करते हैं।stoppedInEmergencyका उपयोग उन फ़ंक्शंस को नियंत्रित करने के लिए किया जाता है जो अनुबंध के कमजोर होने पर दुर्गम होने चाहिए (जैसे,deposit())। इन फ़ंक्शंस के कॉल बस रिवर्ट हो जाएंगे।
onlyWhenStopped का उपयोग उन फ़ंक्शंस के लिए किया जाता है जिन्हें आपात स्थिति के दौरान कॉल किया जाना चाहिए (जैसे, emergencyWithdraw())। ऐसे फ़ंक्शंस स्थिति को हल करने में मदद कर सकते हैं, इसलिए उन्हें "प्रतिबंधित फ़ंक्शंस" सूची से बाहर रखा गया है।
आपातकालीन रोक कार्यक्षमता का उपयोग करना आपके स्मार्ट अनुबंध में गंभीर कमजोरियों से निपटने के लिए एक प्रभावी स्टॉपगैप प्रदान करता है। हालाँकि, यह उपयोगकर्ताओं के लिए डेवलपर्स पर भरोसा करने की आवश्यकता को बढ़ाता है कि वे इसे स्वार्थी कारणों से सक्रिय न करें। इस उद्देश्य के लिए, आपातकालीन रोक के नियंत्रण को विकेंद्रीकृत करना या तो इसे ऑनचेन वोटिंग तंत्र, टाइमलॉक, या मल्टीसिग वॉलेट से अनुमोदन के अधीन करके संभावित समाधान हैं।
इवेंट मॉनिटरिंग
इवेंट (नए टैब में खुलता है) आपको स्मार्ट अनुबंध फ़ंक्शंस के कॉल को ट्रैक करने और स्थिति चर में परिवर्तनों की निगरानी करने की अनुमति देते हैं। जब भी कोई पक्ष सुरक्षा-महत्वपूर्ण कार्रवाई (जैसे, धन की निकासी) करता है, तो इवेंट उत्सर्जित करने के लिए अपने स्मार्ट अनुबंध को प्रोग्राम करना आदर्श है।
इवेंट को लॉग करना और उन्हें ऑफचेन मॉनिटर करना अनुबंध संचालन पर अंतर्दृष्टि प्रदान करता है और दुर्भावनापूर्ण कार्यों की तेजी से खोज में सहायता करता है। इसका मतलब है कि आपकी टीम हैक का तेजी से जवाब दे सकती है और उपयोगकर्ताओं पर प्रभाव को कम करने के लिए कार्रवाई कर सकती है, जैसे फ़ंक्शंस को रोकना या अपग्रेड करना।
आप एक ऑफ-द-शेल्फ मॉनिटरिंग टूल का विकल्प भी चुन सकते हैं जो जब भी कोई आपके अनुबंध के साथ इंटरैक्ट करता है तो स्वचालित रूप से अलर्ट अग्रेषित करता है। ये टूल आपको विभिन्न ट्रिगर्स के आधार पर कस्टम अलर्ट बनाने की अनुमति देंगे, जैसे लेन-देन की मात्रा, फ़ंक्शन कॉल की आवृत्ति, या शामिल विशिष्ट फ़ंक्शंस। उदाहरण के लिए, आप एक अलर्ट प्रोग्राम कर सकते हैं जो तब आता है जब एक ही लेन-देन में निकाली गई राशि एक विशेष सीमा को पार कर जाती है।
7. सुरक्षित शासन प्रणाली डिज़ाइन करें
आप समुदाय के सदस्यों को मुख्य स्मार्ट अनुबंध का नियंत्रण सौंपकर अपने एप्लिकेशन को विकेंद्रीकृत करना चाह सकते हैं। इस मामले में, स्मार्ट अनुबंध सिस्टम में एक शासन मॉड्यूल शामिल होगा—एक तंत्र जो समुदाय के सदस्यों को ऑनचेन शासन प्रणाली के माध्यम से प्रशासनिक कार्यों को स्वीकृति देने की अनुमति देता है। उदाहरण के लिए, एक प्रॉक्सी अनुबंध को नए कार्यान्वयन में अपग्रेड करने के प्रस्ताव पर टोकन-धारकों द्वारा वोट किया जा सकता है।
विकेंद्रीकृत शासन फायदेमंद हो सकता है, खासकर क्योंकि यह डेवलपर्स और अंतिम-उपयोगकर्ताओं के हितों को संरेखित करता है। फिर भी, यदि गलत तरीके से लागू किया जाता है तो स्मार्ट अनुबंध शासन तंत्र नए जोखिम पेश कर सकते हैं। एक प्रशंसनीय परिदृश्य यह है कि यदि कोई हमलावर फ्लैश ऋण लेकर भारी मतदान शक्ति (रखे गए टोकन की संख्या में मापा गया) प्राप्त करता है और एक दुर्भावनापूर्ण प्रस्ताव को आगे बढ़ाता है।
ऑनचेन शासन से संबंधित समस्याओं को रोकने का एक तरीका टाइमलॉक का उपयोग करना (नए टैब में खुलता है) है। एक टाइमलॉक एक स्मार्ट अनुबंध को कुछ कार्यों को निष्पादित करने से रोकता है जब तक कि एक विशिष्ट समय बीत न जाए। अन्य रणनीतियों में प्रत्येक टोकन को "वोटिंग वेट (voting weight)" सौंपना शामिल है, जो इस बात पर आधारित है कि इसे कितने समय के लिए लॉक किया गया है, या वर्तमान ब्लॉक के बजाय ऐतिहासिक अवधि (उदाहरण के लिए, अतीत में 2-3 ब्लॉक) में किसी पते की मतदान शक्ति को मापना। दोनों तरीके ऑनचेन वोटों को स्विंग करने के लिए जल्दी से मतदान शक्ति इकट्ठा करने की संभावना को कम करते हैं।
साझा किए गए लिंक में सुरक्षित शासन प्रणाली डिज़ाइन करने (नए टैब में खुलता है), विकेंद्रीकृत स्वायत्त संगठन (DAO) में विभिन्न मतदान तंत्र (नए टैब में खुलता है), और DeFi का लाभ उठाने वाले सामान्य DAO हमले वैक्टर (नए टैब में खुलता है) के बारे में अधिक जानकारी।
8. कोड में जटिलता को न्यूनतम करें
पारंपरिक सॉफ़्टवेयर डेवलपर KISS ("keep it simple, stupid") सिद्धांत से परिचित हैं, जो सॉफ़्टवेयर डिज़ाइन में अनावश्यक जटिलता पेश करने के खिलाफ सलाह देता है। यह लंबे समय से चली आ रही सोच का अनुसरण करता है कि "जटिल प्रणालियाँ जटिल तरीकों से विफल होती हैं" और महंगी त्रुटियों के प्रति अधिक संवेदनशील होती हैं।
स्मार्ट अनुबंध लिखते समय चीजों को सरल रखना विशेष महत्व का है, यह देखते हुए कि स्मार्ट अनुबंध संभावित रूप से बड़ी मात्रा में मूल्य को नियंत्रित कर रहे हैं। स्मार्ट अनुबंध लिखते समय सरलता प्राप्त करने के लिए एक टिप मौजूदा लाइब्रेरी, जैसे ओपनजेपेलिन कॉन्ट्रैक्ट्स (नए टैब में खुलता है) का पुन: उपयोग करना है, जहां संभव हो। क्योंकि इन लाइब्रेरी का डेवलपर्स द्वारा बड़े पैमाने पर ऑडिट और परीक्षण किया गया है, इसलिए उनका उपयोग करने से खरोंच से नई कार्यक्षमता लिखकर बग पेश करने की संभावना कम हो जाती है।
एक और आम सलाह छोटे फ़ंक्शंस लिखना और कई अनुबंध में व्यावसायिक लॉजिक को विभाजित करके अनुबंध को मॉड्यूलर रखना है। सरल कोड लिखने से न केवल स्मार्ट अनुबंध में हमले की सतह कम होती है, बल्कि समग्र प्रणाली की शुद्धता के बारे में तर्क करना और संभावित डिज़ाइन त्रुटियों का जल्दी पता लगाना भी आसान हो जाता है।
9. सामान्य स्मार्ट अनुबंध कमजोरियों से बचाव करें
पुन:प्रवेश (Reentrancy)
EVM समवर्ती (concurrency) की अनुमति नहीं देता है, जिसका अर्थ है कि संदेश कॉल में शामिल दो अनुबंध एक साथ नहीं चल सकते हैं। एक बाहरी कॉल कॉलिंग अनुबंध के निष्पादन और मेमोरी को तब तक रोक देता है जब तक कि कॉल वापस नहीं आ जाती, जिस बिंदु पर निष्पादन सामान्य रूप से आगे बढ़ता है। इस प्रक्रिया को औपचारिक रूप से किसी अन्य अनुबंध में नियंत्रण प्रवाह (control flow) (नए टैब में खुलता है) स्थानांतरित करने के रूप में वर्णित किया जा सकता है।
हालांकि ज्यादातर हानिरहित, अविश्वसनीय अनुबंध में नियंत्रण प्रवाह को स्थानांतरित करने से पुन:प्रवेश जैसी समस्याएं हो सकती हैं। पुन:प्रवेश हमला तब होता है जब कोई दुर्भावनापूर्ण अनुबंध मूल फ़ंक्शन आमंत्रण पूरा होने से पहले किसी कमजोर अनुबंध में वापस कॉल करता है। इस प्रकार के हमले को एक उदाहरण के साथ सबसे अच्छी तरह समझाया गया है।
एक साधारण स्मार्ट अनुबंध ('Victim') पर विचार करें जो किसी को भी ईथर जमा करने और निकालने की अनुमति देता है:
// यह अनुबंध असुरक्षित है। उत्पादन में उपयोग न करें।
contract Victim {
mapping (address => uint256) public balances;
function deposit() external payable {
balances[msg.sender] += msg.value;
}
function withdraw() external {
uint256 amount = balances[msg.sender];
(bool success, ) = msg.sender.call.value(amount)("");
require(success);
balances[msg.sender] = 0;
}
}
यह अनुबंध उपयोगकर्ताओं को अनुबंध में पहले जमा किए गए ETH को निकालने की अनुमति देने के लिए एक withdraw() फ़ंक्शन को उजागर करता है। निकासी की प्रक्रिया करते समय, अनुबंध निम्नलिखित कार्य करता है:
- उपयोगकर्ता के ETH शेष की जांच करता है
- कॉलिंग पते पर धन भेजता है
- उनके शेष को 0 पर रीसेट करता है, जिससे उपयोगकर्ता से अतिरिक्त निकासी को रोका जा सके
Victim अनुबंध में withdraw() फ़ंक्शन "checks-interactions-effects" पैटर्न का अनुसरण करता है। यह जांच (checks) करता है कि क्या निष्पादन के लिए आवश्यक शर्तें पूरी होती हैं (यानी, उपयोगकर्ता के पास सकारात्मक ETH शेष है) और लेन-देन के प्रभावों (effects) को लागू करने (यानी, उपयोगकर्ता के शेष को कम करने) से पहले कॉलर के पते पर ETH भेजकर इंटरैक्शन (interaction) करता है।
यदि withdraw() को बाह्य स्वामित्व वाले खाते (EOA) से कॉल किया जाता है, तो फ़ंक्शन अपेक्षा के अनुरूप निष्पादित होता है: msg.sender.call.value() कॉलर को ETH भेजता है। हालाँकि, यदि msg.sender एक स्मार्ट अनुबंध खाता है जो withdraw() को कॉल करता है, तो msg.sender.call.value() का उपयोग करके धन भेजने से उस पते पर संग्रहीत कोड भी चलने के लिए ट्रिगर होगा।
कल्पना करें कि यह अनुबंध पते पर तैनात कोड है:
contract Attacker {
function beginAttack() external payable {
Victim(victim_address).deposit.value(1 ether)();
Victim(victim_address).withdraw();
}
function() external payable {
if (gasleft() > 40000) {
Victim(victim_address).withdraw();
}
}
}
यह अनुबंध तीन काम करने के लिए डिज़ाइन किया गया है:
- किसी अन्य खाते (संभवतः हमलावर के EOA) से जमा स्वीकार करना
- Victim अनुबंध में 1 ETH जमा करना
- स्मार्ट अनुबंध में संग्रहीत 1 ETH निकालना
यहां कुछ भी गलत नहीं है, सिवाय इसके कि Attacker में एक और फ़ंक्शन है जो Victim में withdraw() को फिर से कॉल करता है यदि आने वाले msg.sender.call.value से बची हुई गैस 40,000 से अधिक है। यह Attacker को Victim में फिर से प्रवेश करने और withdraw के पहले आमंत्रण के पूरा होने से पहले अधिक धन निकालने की क्षमता देता है। चक्र इस तरह दिखता है:
- Attacker's EOA calls `Attacker.beginAttack()` with 1 ETH
- `Attacker.beginAttack()` deposits 1 ETH into `Victim`
- `Attacker` calls `withdraw() in `Victim`
- `Victim` checks `Attacker`’s balance (1 ETH)
- `Victim` sends 1 ETH to `Attacker` (which triggers the default function)
- `Attacker` calls `Victim.withdraw()` again (note that `Victim` hasn’t reduced `Attacker`’s balance from the first withdrawal)
- `Victim` checks `Attacker`’s balance (which is still 1 ETH because it hasn’t applied the effects of the first call)
- `Victim` sends 1 ETH to `Attacker` (which triggers the default function and allows `Attacker` to reenter the `withdraw` function)
- The process repeats until `Attacker` runs out of gas, at which point `msg.sender.call.value` returns without triggering additional withdrawals
- `Victim` finally applies the results of the first transaction (and subsequent ones) to its state, so `Attacker`’s balance is set to 0
सारांश यह है कि क्योंकि कॉलर का शेष तब तक 0 पर सेट नहीं होता है जब तक कि फ़ंक्शन निष्पादन पूरा नहीं हो जाता, बाद के आमंत्रण सफल होंगे और कॉलर को कई बार अपना शेष निकालने की अनुमति देंगे। इस तरह के हमले का उपयोग स्मार्ट अनुबंध के धन को निकालने के लिए किया जा सकता है, जैसा कि 2016 DAO हैक (नए टैब में खुलता है) में हुआ था। पुन:प्रवेश हमले आज भी स्मार्ट अनुबंध के लिए एक महत्वपूर्ण मुद्दा हैं जैसा कि पुन:प्रवेश कारनामों की सार्वजनिक सूची (नए टैब में खुलता है) दिखाती है।
पुन:प्रवेश हमलों को कैसे रोकें
पुन:प्रवेश से निपटने का एक दृष्टिकोण checks-effects-interactions पैटर्न (नए टैब में खुलता है) का पालन करना है। यह पैटर्न फ़ंक्शंस के निष्पादन को इस तरह से आदेश देता है कि निष्पादन के साथ आगे बढ़ने से पहले आवश्यक जांच करने वाला कोड पहले आता है, उसके बाद वह कोड आता है जो अनुबंध की स्थिति में हेरफेर करता है, और अन्य अनुबंध या EOA के साथ इंटरैक्ट करने वाला कोड अंत में आता है।
checks-effect-interaction पैटर्न का उपयोग नीचे दिखाए गए Victim अनुबंध के संशोधित संस्करण में किया गया है:
contract NoLongerAVictim {
function withdraw() external {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0;
(bool success, ) = msg.sender.call.value(amount)("");
require(success);
}
}
यह अनुबंध उपयोगकर्ता के शेष पर एक जांच (check) करता है, withdraw() फ़ंक्शन के प्रभावों (effects) को लागू करता है (उपयोगकर्ता के शेष को 0 पर रीसेट करके), और इंटरैक्शन (interaction) (उपयोगकर्ता के पते पर ETH भेजना) करने के लिए आगे बढ़ता है। यह सुनिश्चित करता है कि अनुबंध बाहरी कॉल से पहले अपने स्टोरेज को अपडेट करता है, जिससे पुन:प्रवेश की स्थिति समाप्त हो जाती है जिसने पहले हमले को सक्षम किया था। Attacker अनुबंध अभी भी NoLongerAVictim में वापस कॉल कर सकता है, लेकिन चूंकि balances[msg.sender] को 0 पर सेट किया गया है, इसलिए अतिरिक्त निकासी एक त्रुटि फेंक देगी।
एक अन्य विकल्प पारस्परिक बहिष्करण लॉक (mutual exclusion lock) (आमतौर पर "म्यूटेक्स (mutex)" के रूप में वर्णित) का उपयोग करना है जो फ़ंक्शन आमंत्रण पूरा होने तक अनुबंध की स्थिति के एक हिस्से को लॉक कर देता है। इसे एक बूलियन चर का उपयोग करके लागू किया जाता है जिसे फ़ंक्शन निष्पादित होने से पहले true पर सेट किया जाता है और आमंत्रण पूरा होने के बाद false पर वापस आ जाता है। जैसा कि नीचे दिए गए उदाहरण में देखा गया है, म्यूटेक्स का उपयोग किसी फ़ंक्शन को पुनरावर्ती कॉल (recursive calls) से बचाता है जबकि मूल आमंत्रण अभी भी संसाधित हो रहा है, प्रभावी रूप से पुन:प्रवेश को रोकता है।
pragma solidity ^0.7.0;
contract MutexPattern {
bool locked = false;
mapping(address => uint256) public balances;
modifier noReentrancy() {
require(!locked, "Blocked from reentrancy.");
locked = true;
_;
locked = false;
}
// यह फ़ंक्शन एक म्यूटेक्स द्वारा सुरक्षित है, इसलिए `msg.sender.call` के भीतर से पुन:प्रवेश कॉल फिर से `withdraw` को कॉल नहीं कर सकते हैं।
// `return` स्टेटमेंट `true` का मूल्यांकन करता है लेकिन फिर भी मॉडिफायर में `locked = false` स्टेटमेंट का मूल्यांकन करता है
function withdraw(uint _amount) public payable noReentrancy returns(bool) {
require(balances[msg.sender] >= _amount, "No balance to withdraw.");
balances[msg.sender] -= _amount;
(bool success, ) = msg.sender.call{value: _amount}("");
require(success);
return true;
}
}
आप एक पुल भुगतान (pull payments) (नए टैब में खुलता है) प्रणाली का भी उपयोग कर सकते हैं जिसके लिए उपयोगकर्ताओं को स्मार्ट अनुबंध से धन निकालने की आवश्यकता होती है, बजाय "पुश भुगतान (push payments)" प्रणाली के जो खातों में धन भेजती है। यह अज्ञात पतों पर अनजाने में कोड ट्रिगर करने की संभावना को दूर करता है (और कुछ डिनायल-ऑफ़-सर्विस (denial-of-service) हमलों को भी रोक सकता है)।
इंटीजर अंडरफ़्लो और ओवरफ़्लो
एक इंटीजर ओवरफ़्लो तब होता है जब किसी अंकगणितीय संक्रिया का परिणाम मानों की स्वीकार्य सीमा से बाहर हो जाता है, जिससे यह सबसे कम प्रस्तुत करने योग्य मान पर "रोल ओवर" हो जाता है। उदाहरण के लिए, एक uint8 केवल 2^8-1=255 तक के मान संग्रहीत कर सकता है। अंकगणितीय संक्रियाएं जिनके परिणामस्वरूप 255 से अधिक मान होते हैं, वे ओवरफ़्लो हो जाएंगे और uint को 0 पर रीसेट कर देंगे, ठीक उसी तरह जैसे कार का ओडोमीटर अधिकतम माइलेज (999999) तक पहुंचने के बाद 0 पर रीसेट हो जाता है।
इंटीजर अंडरफ़्लो समान कारणों से होते हैं: अंकगणितीय संक्रिया का परिणाम स्वीकार्य सीमा से नीचे आ जाता है। मान लीजिए कि आपने uint8 में 0 को कम करने का प्रयास किया, तो परिणाम बस अधिकतम प्रस्तुत करने योग्य मान (255) पर रोल ओवर हो जाएगा।
इंटीजर ओवरफ़्लो और अंडरफ़्लो दोनों अनुबंध के स्थिति चर में अप्रत्याशित परिवर्तन ला सकते हैं और अनियोजित निष्पादन का परिणाम हो सकते हैं। नीचे एक उदाहरण दिया गया है जो दिखाता है कि कैसे एक हमलावर अमान्य संचालन करने के लिए स्मार्ट अनुबंध में अंकगणितीय ओवरफ़्लो का फायदा उठा सकता है:
pragma solidity ^0.7.6;
// यह अनुबंध एक टाइम वॉल्ट के रूप में कार्य करने के लिए डिज़ाइन किया गया है।
// उपयोगकर्ता इस अनुबंध में जमा कर सकता है लेकिन कम से कम एक सप्ताह तक निकाल नहीं सकता है।
// उपयोगकर्ता प्रतीक्षा समय को 1 सप्ताह की प्रतीक्षा अवधि से आगे भी बढ़ा सकता है।
/*
1. TimeLock डिप्लॉय करें
2. TimeLock के पते के साथ Attack डिप्लॉय करें
3. 1 ईथर भेजकर Attack.attack को कॉल करें। आप तुरंत अपना ईथर निकाल सकेंगे।
क्या हुआ?
Attack के कारण TimeLock.lockTime ओवरफ़्लो हो गया और 1 सप्ताह की प्रतीक्षा अवधि से पहले निकालने में सक्षम हो गया।
*/
contract TimeLock {
mapping(address => uint) public balances;
mapping(address => uint) public lockTime;
function deposit() external payable {
balances[msg.sender] += msg.value;
lockTime[msg.sender] = block.timestamp + 1 weeks;
}
function increaseLockTime(uint _secondsToIncrease) public {
lockTime[msg.sender] += _secondsToIncrease;
}
function withdraw() public {
require(balances[msg.sender] > 0, "Insufficient funds");
require(block.timestamp > lockTime[msg.sender], "Lock time not expired");
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
(bool sent, ) = msg.sender.call{value: amount}("");
require(sent, "Failed to send Ether");
}
}
contract Attack {
TimeLock timeLock;
constructor(TimeLock _timeLock) {
timeLock = TimeLock(_timeLock);
}
fallback() external payable {}
function attack() public payable {
timeLock.deposit{value: msg.value}();
/*
यदि t = वर्तमान लॉक समय है तो हमें x ऐसा खोजना होगा कि
x + t = 2**256 = 0
इसलिए x = -t
2**256 = type(uint).max + 1
इसलिए x = type(uint).max + 1 - t
*/
timeLock.increaseLockTime(
type(uint).max + 1 - timeLock.lockTime(address(this))
);
timeLock.withdraw();
}
}
इंटीजर अंडरफ़्लो और ओवरफ़्लो को कैसे रोकें
संस्करण 0.8.0 के अनुसार, Solidity कंपाइलर उस कोड को अस्वीकार कर देता है जिसके परिणामस्वरूप इंटीजर अंडरफ़्लो और ओवरफ़्लो होते हैं। हालाँकि, कम कंपाइलर संस्करण के साथ संकलित अनुबंध को या तो अंकगणितीय संक्रियाओं से जुड़े फ़ंक्शंस पर जांच करनी चाहिए या एक लाइब्रेरी (जैसे, SafeMath (नए टैब में खुलता है)) का उपयोग करना चाहिए जो अंडरफ़्लो/ओवरफ़्लो की जांच करती है।
ऑरेकल हेरफेर
ऑरेकल ऑफचेन जानकारी प्राप्त करते हैं और इसे स्मार्ट अनुबंध के उपयोग के लिए ऑनचेन भेजते हैं। ऑरेकल के साथ, आप ऐसे स्मार्ट अनुबंध डिज़ाइन कर सकते हैं जो ऑफचेन सिस्टम, जैसे पूंजी बाजार के साथ इंटरऑपरेट करते हैं, जिससे उनके एप्लिकेशन का काफी विस्तार होता है।
लेकिन अगर ऑरेकल दूषित हो जाता है और ऑनचेन गलत जानकारी भेजता है, तो स्मार्ट अनुबंध गलत इनपुट के आधार पर निष्पादित होंगे, जिससे समस्याएं हो सकती हैं। यह "ओरेकल समस्या" का आधार है, जो यह सुनिश्चित करने के कार्य से संबंधित है कि ब्लॉकचेन ओरेकल से जानकारी सटीक, अद्यतित और समय पर हो।
एक संबंधित सुरक्षा चिंता किसी संपत्ति के लिए हाजिर मूल्य (spot price) प्राप्त करने के लिए ऑनचेन ऑरेकल, जैसे विकेंद्रीकृत एक्सचेंज (DEX) का उपयोग करना है। विकेंद्रीकृत वित्त (DeFi) उद्योग में ऋण देने वाले प्लेटफ़ॉर्म अक्सर उपयोगकर्ता के संपार्श्विक (collateral) का मूल्य निर्धारित करने के लिए ऐसा करते हैं ताकि यह निर्धारित किया जा सके कि वे कितना उधार ले सकते हैं।
DEX की कीमतें अक्सर सटीक होती हैं, जिसका मुख्य कारण बाजारों में समानता बहाल करने वाले मध्यस्थ (arbitrageurs) हैं। हालाँकि, वे हेरफेर के लिए खुले हैं, खासकर यदि ऑनचेन ऑरेकल ऐतिहासिक ट्रेडिंग पैटर्न के आधार पर संपत्ति की कीमतों की गणना करता है (जैसा कि आमतौर पर होता है)।
उदाहरण के लिए, एक हमलावर आपके ऋण देने वाले अनुबंध के साथ इंटरैक्ट करने से ठीक पहले फ्लैश ऋण लेकर किसी संपत्ति के हाजिर मूल्य को कृत्रिम रूप से बढ़ा सकता है। संपत्ति की कीमत के लिए DEX से पूछताछ करने पर सामान्य से अधिक मूल्य वापस आएगा (हमलावर के बड़े "खरीद आदेश" के कारण संपत्ति की मांग में वृद्धि), जिससे उन्हें अपनी क्षमता से अधिक उधार लेने की अनुमति मिलेगी। इस तरह के "फ्लैश ऋण हमलों" का उपयोग DeFi एप्लिकेशन के बीच मूल्य ऑरेकल पर निर्भरता का फायदा उठाने के लिए किया गया है, जिससे प्रोटोकॉल को खोए हुए धन में लाखों का नुकसान हुआ है।
ऑरेकल हेरफेर को कैसे रोकें
ऑरेकल हेरफेर से बचने (नए टैब में खुलता है) के लिए न्यूनतम आवश्यकता एक विकेंद्रीकृत ऑरेकल नेटवर्क का उपयोग करना है जो विफलता के एकल बिंदुओं से बचने के लिए कई स्रोतों से जानकारी प्राप्त करता है। ज्यादातर मामलों में, विकेंद्रीकृत ऑरेकल में ऑरेकल नोड्स को सही जानकारी की रिपोर्ट करने के लिए प्रोत्साहित करने के लिए अंतर्निहित क्रिप्टो-आर्थिक प्रोत्साहन होते हैं, जिससे वे केंद्रीकृत ऑरेकल की तुलना में अधिक सुरक्षित हो जाते हैं।
यदि आप संपत्ति की कीमतों के लिए ऑनचेन ऑरेकल से पूछताछ करने की योजना बना रहे हैं, तो ऐसे ऑरेकल का उपयोग करने पर विचार करें जो समय-भारित औसत मूल्य (TWAP) तंत्र लागू करता है। एक TWAP ऑरेकल (नए टैब में खुलता है) समय के दो अलग-अलग बिंदुओं (जिन्हें आप संशोधित कर सकते हैं) पर किसी संपत्ति की कीमत पूछता है और प्राप्त औसत के आधार पर हाजिर मूल्य की गणना करता है। लंबी समयावधि चुनना आपके प्रोटोकॉल को मूल्य हेरफेर से बचाता है क्योंकि हाल ही में निष्पादित बड़े आदेश संपत्ति की कीमतों को प्रभावित नहीं कर सकते हैं।
डेवलपर्स के लिए स्मार्ट अनुबंध सुरक्षा संसाधन
स्मार्ट अनुबंधों का विश्लेषण करने और कोड की शुद्धता को सत्यापित करने के लिए टूल
-
परीक्षण टूल और लाइब्रेरी - स्मार्ट अनुबंधों पर यूनिट परीक्षण, स्थिर विश्लेषण और गतिशील विश्लेषण करने के लिए उद्योग-मानक टूल और लाइब्रेरी का संग्रह।
-
औपचारिक सत्यापन टूल - स्मार्ट अनुबंधों में कार्यात्मक शुद्धता को सत्यापित करने और इनवेरिएंट्स की जांच करने के लिए टूल।
-
स्मार्ट अनुबंध ऑडिटिंग सेवाएँ - इथेरियम विकास परियोजनाओं के लिए स्मार्ट अनुबंध ऑडिटिंग सेवाएँ प्रदान करने वाले संगठनों की सूची।
-
बग बाउंटी प्लेटफ़ॉर्म - बग बाउंटी का समन्वय करने और स्मार्ट अनुबंधों में महत्वपूर्ण कमजोरियों के जिम्मेदार प्रकटीकरण को पुरस्कृत करने के लिए प्लेटफ़ॉर्म।
-
Fork Checker (नए टैब में खुलता है) - फ़ोर्क किए गए अनुबंध के संबंध में सभी उपलब्ध जानकारी की जांच करने के लिए एक मुफ़्त ऑनलाइन टूल।
-
ABI Encoder (नए टैब में खुलता है) - आपके Solidity अनुबंध फ़ंक्शंस और कंस्ट्रक्टर तर्कों को एन्कोड करने के लिए एक मुफ़्त ऑनलाइन सेवा।
-
Aderyn (नए टैब में खुलता है) - Solidity स्टेटिक एनालाइज़र, जो संदिग्ध कमजोरियों को इंगित करने के लिए एब्सट्रैक्ट सिंटैक्स ट्री (AST) को पार करता है और आसानी से उपयोग किए जाने वाले मार्कडाउन प्रारूप में समस्याओं को प्रिंट करता है।
स्मार्ट अनुबंधों की निगरानी के लिए टूल
- Tenderly रियल-टाइम अलर्टिंग (नए टैब में खुलता है) - आपके स्मार्ट अनुबंधों या वॉलेट पर असामान्य या अप्रत्याशित घटनाएँ होने पर रीयल-टाइम सूचनाएं प्राप्त करने के लिए एक टूल।
स्मार्ट अनुबंधों के सुरक्षित प्रशासन के लिए टूल
-
Safe (नए टैब में खुलता है) - इथेरियम पर चलने वाला स्मार्ट अनुबंध वॉलेट जिसे किसी लेन-देन के होने से पहले उसे स्वीकृति देने के लिए न्यूनतम संख्या में लोगों की आवश्यकता होती है (M-of-N)।
-
ओपनजेपेलिन कॉन्ट्रैक्ट्स (नए टैब में खुलता है) - अनुबंध स्वामित्व, अपग्रेड, एक्सेस कंट्रोल, शासन, पॉज़ेबिलिटी और बहुत कुछ सहित प्रशासनिक सुविधाओं को लागू करने के लिए अनुबंध लाइब्रेरी।
स्मार्ट अनुबंध ऑडिटिंग सेवाएँ
-
कॉन्सेन्सिस डिलिजेंस (नए टैब में खुलता है) - स्मार्ट अनुबंध ऑडिटिंग सेवा जो ब्लॉकचेन इकोसिस्टम में परियोजनाओं को यह सुनिश्चित करने में मदद करती है कि उनके प्रोटोकॉल लॉन्च के लिए तैयार हैं और उपयोगकर्ताओं की सुरक्षा के लिए बनाए गए हैं।
-
CertiK (नए टैब में खुलता है) - ब्लॉकचेन सुरक्षा फर्म जो स्मार्ट अनुबंधों और ब्लॉकचेन नेटवर्क पर अत्याधुनिक औपचारिक सत्यापन तकनीक के उपयोग में अग्रणी है।
-
Trail of Bits (नए टैब में खुलता है) - साइबर सुरक्षा कंपनी जो जोखिम को कम करने और कोड को मजबूत करने के लिए हमलावर मानसिकता के साथ सुरक्षा अनुसंधान को जोड़ती है।
-
PeckShield (नए टैब में खुलता है) - ब्लॉकचेन सुरक्षा कंपनी जो संपूर्ण ब्लॉकचेन इकोसिस्टम की सुरक्षा, गोपनीयता और उपयोगिता के लिए उत्पाद और सेवाएँ प्रदान करती है।
-
QuantStamp (नए टैब में खुलता है) - ऑडिटिंग सेवा जो सुरक्षा और जोखिम मूल्यांकन सेवाओं के माध्यम से ब्लॉकचेन तकनीक को मुख्यधारा में अपनाने की सुविधा प्रदान करती है।
-
ओपनजेपेलिन (नए टैब में खुलता है) - स्मार्ट अनुबंध सुरक्षा कंपनी जो वितरित प्रणालियों के लिए सुरक्षा ऑडिट प्रदान करती है।
-
Runtime Verification (नए टैब में खुलता है) - सुरक्षा कंपनी जो स्मार्ट अनुबंधों के औपचारिक मॉडलिंग और सत्यापन में विशेषज्ञता रखती है।
-
Hacken (नए टैब में खुलता है) - Web3 साइबर सुरक्षा ऑडिटर जो ब्लॉकचेन सुरक्षा के लिए 360-डिग्री दृष्टिकोण लाता है।
-
नेदरमाइंड (नए टैब में खुलता है) - Solidity और Cairo ऑडिटिंग सेवाएँ, जो इथेरियम और स्टार्कनेट पर स्मार्ट अनुबंधों की अखंडता और उपयोगकर्ताओं की सुरक्षा सुनिश्चित करती हैं।
-
HashEx (नए टैब में खुलता है) - HashEx क्रिप्टोकरेंसी की सुरक्षा सुनिश्चित करने के लिए ब्लॉकचेन और स्मार्ट अनुबंध ऑडिटिंग पर ध्यान केंद्रित करता है, जो स्मार्ट अनुबंध विकास, पेनेट्रेशन परीक्षण, ब्लॉकचेन परामर्श जैसी सेवाएँ प्रदान करता है।
-
Code4rena (नए टैब में खुलता है) - प्रतिस्पर्धी ऑडिट प्लेटफ़ॉर्म जो स्मार्ट अनुबंध सुरक्षा विशेषज्ञों को कमजोरियों को खोजने और Web3 को अधिक सुरक्षित बनाने में मदद करने के लिए प्रोत्साहित करता है।
-
CodeHawks (नए टैब में खुलता है) - प्रतिस्पर्धी ऑडिट प्लेटफ़ॉर्म जो सुरक्षा शोधकर्ताओं के लिए स्मार्ट अनुबंध ऑडिटिंग प्रतियोगिताओं की मेजबानी करता है।
-
Cyfrin (नए टैब में खुलता है) - Web3 सुरक्षा पावरहाउस, जो उत्पादों और स्मार्ट अनुबंध ऑडिटिंग सेवाओं के माध्यम से क्रिप्टो सुरक्षा को विकसित करता है।
-
ImmuneBytes (नए टैब में खुलता है) - Web3 सुरक्षा फर्म जो अनुभवी ऑडिटरों की एक टीम और सर्वश्रेष्ठ-इन-क्लास टूल के माध्यम से ब्लॉकचेन सिस्टम के लिए सुरक्षा ऑडिट प्रदान करती है।
-
Oxorio (नए टैब में खुलता है) - क्रिप्टो फर्मों और विकेंद्रीकृत वित्त (DeFi) परियोजनाओं के लिए EVM, Solidity, ZK, क्रॉस-चेन तकनीक में विशेषज्ञता के साथ स्मार्ट अनुबंध ऑडिट और ब्लॉकचेन सुरक्षा सेवाएँ।
-
Inference (नए टैब में खुलता है) - सुरक्षा ऑडिटिंग कंपनी, जो EVM-आधारित ब्लॉकचेन के लिए स्मार्ट अनुबंध ऑडिटिंग में विशेषज्ञता रखती है। इसके विशेषज्ञ ऑडिटरों की बदौलत वे संभावित समस्याओं की पहचान करते हैं और तैनाती से पहले उन्हें ठीक करने के लिए कार्रवाई योग्य समाधान सुझाते हैं।
बग बाउंटी प्लेटफ़ॉर्म
-
Immunefi (नए टैब में खुलता है) - स्मार्ट अनुबंधों और विकेंद्रीकृत वित्त (DeFi) परियोजनाओं के लिए बग बाउंटी प्लेटफ़ॉर्म, जहाँ सुरक्षा शोधकर्ता कोड की समीक्षा करते हैं, कमजोरियों का खुलासा करते हैं, भुगतान प्राप्त करते हैं और क्रिप्टो को अधिक सुरक्षित बनाते हैं।
-
HackerOne (नए टैब में खुलता है) - भेद्यता समन्वय और बग बाउंटी प्लेटफ़ॉर्म जो व्यवसायों को पेनेट्रेशन परीक्षकों और साइबर सुरक्षा शोधकर्ताओं से जोड़ता है।
-
HackenProof (नए टैब में खुलता है) - क्रिप्टो परियोजनाओं (DeFi, स्मार्ट अनुबंध, वॉलेट, CEX और बहुत कुछ) के लिए विशेषज्ञ बग बाउंटी प्लेटफ़ॉर्म, जहाँ सुरक्षा पेशेवर ट्राइएज सेवाएँ प्रदान करते हैं और शोधकर्ताओं को प्रासंगिक, सत्यापित बग रिपोर्ट के लिए भुगतान मिलता है।
-
Sherlock (नए टैब में खुलता है) - स्मार्ट अनुबंध सुरक्षा के लिए Web3 में अंडरराइटर, जिसमें ऑडिटरों के लिए भुगतान स्मार्ट अनुबंधों के माध्यम से प्रबंधित किया जाता है ताकि यह सुनिश्चित किया जा सके कि प्रासंगिक बग का उचित भुगतान किया जाए।
-
CodeHawks (नए टैब में खुलता है) - प्रतिस्पर्धी बग बाउंटी प्लेटफ़ॉर्म जहाँ ऑडिटर सुरक्षा प्रतियोगिताओं और चुनौतियों में भाग लेते हैं, और (जल्द ही) अपने स्वयं के निजी ऑडिट में।
ज्ञात स्मार्ट अनुबंध कमजोरियों और एक्सप्लॉइट्स के प्रकाशन
-
कॉन्सेन्सिस: स्मार्ट अनुबंध ज्ञात हमले (नए टैब में खुलता है) - अधिकांश मामलों के लिए नमूना कोड के साथ, सबसे महत्वपूर्ण अनुबंध कमजोरियों का शुरुआती-अनुकूल स्पष्टीकरण।
-
SWC रजिस्ट्री (नए टैब में खुलता है) - कॉमन वीकनेस एन्यूमरेशन (CWE) आइटम की क्यूरेटेड सूची जो इथेरियम स्मार्ट अनुबंधों पर लागू होती है।
-
Rekt (नए टैब में खुलता है) - विस्तृत पोस्ट-मॉर्टम रिपोर्ट के साथ हाई-प्रोफाइल क्रिप्टो हैक और एक्सप्लॉइट्स का नियमित रूप से अपडेट किया जाने वाला प्रकाशन।
स्मार्ट अनुबंध सुरक्षा सीखने के लिए चुनौतियाँ
-
Awesome BlockSec CTF (नए टैब में खुलता है) - ब्लॉकचेन सुरक्षा वॉरगेम्स, चुनौतियों, और कैप्चर द फ्लैग (नए टैब में खुलता है) प्रतियोगिताओं और समाधान राइटअप की क्यूरेटेड सूची।
-
Damn Vulnerable DeFi (नए टैब में खुलता है) - विकेंद्रीकृत वित्त (DeFi) स्मार्ट अनुबंधों की आक्रामक सुरक्षा सीखने और बग-हंटिंग और सुरक्षा ऑडिटिंग में कौशल बनाने के लिए वॉरगेम।
-
Ethernaut (नए टैब में खुलता है) - Web3/Solidity-आधारित वॉरगेम जहाँ प्रत्येक स्तर एक स्मार्ट अनुबंध है जिसे 'हैक' करने की आवश्यकता होती है।
-
HackenProof x HackTheBox (नए टैब में खुलता है) - एक फंतासी साहसिक कार्य पर आधारित स्मार्ट अनुबंध हैकिंग चुनौती। चुनौती को सफलतापूर्वक पूरा करने से एक निजी बग बाउंटी कार्यक्रम तक पहुंच भी मिलती है।
स्मार्ट अनुबंधों को सुरक्षित करने के लिए सर्वोत्तम प्रथाएँ
-
कॉन्सेन्सिस: इथेरियम स्मार्ट अनुबंध सुरक्षा सर्वोत्तम प्रथाएँ (नए टैब में खुलता है) - इथेरियम स्मार्ट अनुबंधों को सुरक्षित करने के लिए दिशानिर्देशों की व्यापक सूची।
-
Nascent: सिंपल सिक्योरिटी टूलकिट (नए टैब में खुलता है) - स्मार्ट अनुबंध विकास के लिए व्यावहारिक सुरक्षा-केंद्रित गाइड और चेकलिस्ट का संग्रह।
-
Solidity पैटर्न्स (नए टैब में खुलता है) - स्मार्ट अनुबंध प्रोग्रामिंग भाषा Solidity के लिए सुरक्षित पैटर्न और सर्वोत्तम प्रथाओं का उपयोगी संकलन।
-
Solidity डॉक्स: सुरक्षा संबंधी विचार (नए टैब में खुलता है) - Solidity के साथ सुरक्षित स्मार्ट अनुबंध लिखने के लिए दिशानिर्देश।
-
स्मार्ट अनुबंध सुरक्षा सत्यापन मानक (नए टैब में खुलता है) - डेवलपर्स, आर्किटेक्ट्स, सुरक्षा समीक्षकों और विक्रेताओं के लिए स्मार्ट अनुबंधों की सुरक्षा को मानकीकृत करने के लिए बनाई गई चौदह-भाग वाली चेकलिस्ट।
-
स्मार्ट अनुबंध सुरक्षा और ऑडिटिंग सीखें (नए टैब में खुलता है) - अंतिम स्मार्ट अनुबंध सुरक्षा और ऑडिटिंग कोर्स, जो उन स्मार्ट अनुबंध डेवलपर्स के लिए बनाया गया है जो अपनी सुरक्षा सर्वोत्तम प्रथाओं को बेहतर बनाना चाहते हैं और सुरक्षा शोधकर्ता बनना चाहते हैं।