स्मार्ट अनुबंध सुरक्षा
स्मार्ट अनुबंध अत्यधिक लचीले होते हैं, और ब्लॉकचेन पर तैनात कोड के आधार पर अपरिवर्तनीय लॉजिक चलाते हुए बड़ी मात्रा में मूल्य और डेटा को नियंत्रित करने में सक्षम होते हैं। इसने विश्वासहीन और विकेंद्रीकृत एप्लिकेशन का एक जीवंत इकोसिस्टम बनाया है जो पुराने सिस्टम की तुलना में कई लाभ प्रदान करते हैं। वे उन हमलावरों के लिए अवसर भी प्रस्तुत करते हैं जो स्मार्ट अनुबंधों में कमजोरियों का फायदा उठाकर लाभ कमाना चाहते हैं।
सार्वजनिक ब्लॉकचेन, जैसे इथेरियम, स्मार्ट अनुबंधों को सुरक्षित करने के मुद्दे को और जटिल बनाते हैं। तैनात किए गए अनुबंध कोड को आमतौर पर सुरक्षा खामियों को ठीक करने के लिए बदला नहीं जा सकता है, जबकि स्मार्ट अनुबंधों से चुराई गई संपत्तियों को ट्रैक करना बेहद मुश्किल होता है और अपरिवर्तनीयता के कारण वे ज्यादातर अप्राप्य होती हैं।
हालांकि आंकड़े अलग-अलग हैं, यह अनुमान है कि स्मार्ट अनुबंधों में सुरक्षा दोषों के कारण चुराए गए या खोए गए मूल्य की कुल राशि आसानी से $1 बिलियन से अधिक है। इसमें हाई-प्रोफाइल घटनाएं शामिल हैं, जैसे कि DAO हैक (opens in a new tab) (3.6M ETH चुराए गए, जिनकी आज की कीमत $1B से अधिक है), Parity मल्टीसिग वॉलेट हैक (opens in a new tab) (हैकर्स द्वारा $30M का नुकसान), और Parity फ्रोजन वॉलेट समस्या (opens in a new tab) (हमेशा के लिए लॉक किए गए $300M से अधिक के ETH)।
उपर्युक्त समस्याएं डेवलपर्स के लिए सुरक्षित, मजबूत और लचीले स्मार्ट अनुबंध बनाने में प्रयास करना अनिवार्य बनाती हैं। स्मार्ट अनुबंध सुरक्षा एक गंभीर विषय है, और इसे सीखना हर डेवलपर के लिए फायदेमंद होगा। यह मार्गदर्शिका इथेरियम डेवलपर्स के लिए सुरक्षा संबंधी विचारों को कवर करेगी और स्मार्ट अनुबंध सुरक्षा में सुधार के लिए संसाधनों का पता लगाएगी।
पूर्वापेक्षाएँ
सुरक्षा से निपटने से पहले सुनिश्चित करें कि आप स्मार्ट अनुबंध विकास के मूल सिद्धांतों से परिचित हैं।
सुरक्षित इथेरियम स्मार्ट अनुबंध बनाने के लिए दिशानिर्देश
1. उचित एक्सेस कंट्रोल डिज़ाइन करें
स्मार्ट अनुबंधों में, public या external के रूप में चिह्नित फ़ंक्शंस को किसी भी बाहरी स्वामित्व वाले खातों (EOA) या अनुबंध खातों द्वारा कॉल किया जा सकता है। यदि आप चाहते हैं कि अन्य लोग आपके अनुबंध के साथ इंटरैक्ट करें, तो फ़ंक्शंस के लिए सार्वजनिक दृश्यता (public visibility) निर्दिष्ट करना आवश्यक है। हालाँकि, private के रूप में चिह्नित फ़ंक्शंस को केवल स्मार्ट अनुबंध के भीतर के फ़ंक्शंस द्वारा ही कॉल किया जा सकता है, बाहरी खातों द्वारा नहीं। प्रत्येक नेटवर्क प्रतिभागी को अनुबंध फ़ंक्शंस तक पहुंच देने से समस्याएँ हो सकती हैं, खासकर यदि इसका मतलब है कि कोई भी संवेदनशील संचालन (जैसे, नए टोकन की मिंटिंग) कर सकता है।
स्मार्ट अनुबंध फ़ंक्शंस के अनधिकृत उपयोग को रोकने के लिए, सुरक्षित एक्सेस कंट्रोल लागू करना आवश्यक है। एक्सेस कंट्रोल तंत्र एक स्मार्ट अनुबंध में कुछ फ़ंक्शंस का उपयोग करने की क्षमता को स्वीकृत संस्थाओं तक सीमित करते हैं, जैसे कि अनुबंध के प्रबंधन के लिए जिम्मेदार खाते। Ownable पैटर्न और भूमिका-आधारित नियंत्रण (role-based control) स्मार्ट अनुबंधों में एक्सेस कंट्रोल लागू करने के लिए उपयोगी दो पैटर्न हैं:
Ownable पैटर्न
Ownable पैटर्न में, अनुबंध-निर्माण प्रक्रिया के दौरान एक पता को अनुबंध के “मालिक (owner)” के रूप में सेट किया जाता है। संरक्षित फ़ंक्शंस को एक OnlyOwner संशोधक (modifier) सौंपा जाता है, जो यह सुनिश्चित करता है कि अनुबंध फ़ंक्शन को निष्पादित करने से पहले कॉल करने वाले पते की पहचान को प्रमाणित करता है। अनुबंध के मालिक के अलावा अन्य पतों से संरक्षित फ़ंक्शंस पर कॉल हमेशा रिवर्ट हो जाती हैं, जिससे अवांछित पहुंच को रोका जा सकता है।
भूमिका-आधारित एक्सेस कंट्रोल
स्मार्ट अनुबंध में एक ही पते को Owner के रूप में पंजीकृत करने से केंद्रीकरण का जोखिम उत्पन्न होता है और यह विफलता के एकल बिंदु (single point-of-failure) का प्रतिनिधित्व करता है। यदि मालिक के खाते की कुंजियों (keys) से समझौता किया जाता है, तो हमलावर स्वामित्व वाले अनुबंध पर हमला कर सकते हैं। यही कारण है कि कई प्रशासनिक खातों के साथ भूमिका-आधारित एक्सेस कंट्रोल पैटर्न का उपयोग करना एक बेहतर विकल्प हो सकता है।
भूमिका-आधारित एक्सेस कंट्रोल में, संवेदनशील फ़ंक्शंस तक पहुंच विश्वसनीय प्रतिभागियों के एक समूह के बीच वितरित की जाती है। उदाहरण के लिए, एक खाता टोकन की मिंटिंग के लिए जिम्मेदार हो सकता है, जबकि दूसरा खाता अपग्रेड करता है या अनुबंध को रोकता है। इस तरह एक्सेस कंट्रोल को विकेंद्रीकृत करने से विफलता के एकल बिंदु समाप्त हो जाते हैं और उपयोगकर्ताओं के लिए विश्वास मान्यताएँ कम हो जाती हैं।
बहु-हस्ताक्षर वॉलेट का उपयोग करना
सुरक्षित एक्सेस कंट्रोल लागू करने का एक अन्य दृष्टिकोण अनुबंध का प्रबंधन करने के लिए बहु-हस्ताक्षर खाते का उपयोग करना है। एक नियमित EOA के विपरीत, बहु-हस्ताक्षर खातों का स्वामित्व कई संस्थाओं के पास होता है और लेन-देन निष्पादित करने के लिए न्यूनतम संख्या में खातों—मान लीजिए 5 में से 3—से हस्ताक्षर की आवश्यकता होती है।
एक्सेस कंट्रोल के लिए मल्टीसिग का उपयोग करने से सुरक्षा की एक अतिरिक्त परत जुड़ जाती है क्योंकि लक्ष्य अनुबंध पर कार्रवाई के लिए कई पक्षों की सहमति की आवश्यकता होती है। यह विशेष रूप से उपयोगी है यदि Ownable पैटर्न का उपयोग करना आवश्यक है, क्योंकि यह किसी हमलावर या दुष्ट अंदरूनी सूत्र के लिए दुर्भावनापूर्ण उद्देश्यों के लिए संवेदनशील अनुबंध फ़ंक्शंस में हेरफेर करना अधिक कठिन बना देता है।
2. अनुबंध संचालन की सुरक्षा के लिए require(), assert(), और revert() कथनों का उपयोग करें
जैसा कि उल्लेख किया गया है, एक बार ब्लॉकचेन पर तैनात होने के बाद कोई भी आपके स्मार्ट अनुबंध में सार्वजनिक फ़ंक्शंस को कॉल कर सकता है। चूँकि आप पहले से नहीं जान सकते कि बाहरी खाते किसी अनुबंध के साथ कैसे इंटरैक्ट करेंगे, इसलिए तैनाती से पहले समस्याग्रस्त संचालन के खिलाफ आंतरिक सुरक्षा उपाय लागू करना आदर्श है। यदि निष्पादन कुछ आवश्यकताओं को पूरा करने में विफल रहता है, तो आप अपवादों (exceptions) को ट्रिगर करने और स्थिति परिवर्तनों को रिवर्ट करने के लिए require(), assert(), और revert() कथनों का उपयोग करके स्मार्ट अनुबंधों में सही व्यवहार लागू कर सकते हैं।
require(): require फ़ंक्शंस की शुरुआत में परिभाषित किए जाते हैं और यह सुनिश्चित करते हैं कि कॉल किए गए फ़ंक्शन के निष्पादित होने से पहले पूर्व-निर्धारित शर्तें पूरी हों। एक require कथन का उपयोग उपयोगकर्ता इनपुट को मान्य करने, स्थिति चर (state variables) की जांच करने, या किसी फ़ंक्शन के साथ आगे बढ़ने से पहले कॉल करने वाले खाते की पहचान को प्रमाणित करने के लिए किया जा सकता है।
assert(): assert() का उपयोग आंतरिक त्रुटियों का पता लगाने और आपके कोड में “इनवेरिएंट्स (invariants)” के उल्लंघन की जांच करने के लिए किया जाता है। एक इनवेरिएंट किसी अनुबंध की स्थिति के बारे में एक तार्किक दावा है जो सभी फ़ंक्शन निष्पादन के लिए सत्य होना चाहिए। एक उदाहरण इनवेरिएंट किसी टोकन अनुबंध की अधिकतम कुल आपूर्ति या शेष राशि है। assert() का उपयोग यह सुनिश्चित करता है कि आपका अनुबंध कभी भी असुरक्षित स्थिति में न पहुंचे, और यदि ऐसा होता है, तो स्थिति चर में किए गए सभी परिवर्तन वापस ले लिए जाते हैं (rolled 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. स्मार्ट अनुबंधों का परीक्षण करें और कोड की शुद्धता सत्यापित करें
इथेरियम वर्चुअल मशीन में चलने वाले कोड की अपरिवर्तनीयता का मतलब है कि स्मार्ट अनुबंध विकास चरण के दौरान उच्च स्तर के गुणवत्ता मूल्यांकन की मांग करते हैं। अपने अनुबंध का बड़े पैमाने पर परीक्षण करना और किसी भी अप्रत्याशित परिणाम के लिए इसका अवलोकन करना सुरक्षा में काफी सुधार करेगा और लंबे समय में आपके उपयोगकर्ताओं की रक्षा करेगा।
सामान्य तरीका मॉक डेटा का उपयोग करके छोटे यूनिट परीक्षण लिखना है जो अनुबंध को उपयोगकर्ताओं से प्राप्त होने की उम्मीद है। यूनिट परीक्षण कुछ फ़ंक्शंस की कार्यक्षमता का परीक्षण करने और यह सुनिश्चित करने के लिए अच्छा है कि एक स्मार्ट अनुबंध अपेक्षा के अनुरूप काम करता है।
दुर्भाग्य से, जब अलग से उपयोग किया जाता है तो स्मार्ट अनुबंध सुरक्षा में सुधार के लिए यूनिट परीक्षण न्यूनतम रूप से प्रभावी होता है। एक यूनिट परीक्षण यह साबित कर सकता है कि एक फ़ंक्शन मॉक डेटा के लिए ठीक से निष्पादित होता है, लेकिन यूनिट परीक्षण केवल उतने ही प्रभावी होते हैं जितने कि लिखे गए परीक्षण। इससे छूटे हुए एज केस (edge cases) और कमजोरियों का पता लगाना मुश्किल हो जाता है जो आपके स्मार्ट अनुबंध की सुरक्षा को तोड़ सकते हैं।
एक बेहतर दृष्टिकोण यूनिट परीक्षण को स्थिर और गतिशील विश्लेषण (static and dynamic analysis) का उपयोग करके किए गए संपत्ति-आधारित परीक्षण (property-based testing) के साथ जोड़ना है। स्थिर विश्लेषण पहुंच योग्य प्रोग्राम स्थितियों और निष्पादन पथों का विश्लेषण करने के लिए निम्न-स्तरीय अभ्यावेदन, जैसे नियंत्रण प्रवाह ग्राफ़ (control flow graphs) (opens in a new tab) और अमूर्त सिंटैक्स ट्री (abstract syntax trees) (opens in a new tab) पर निर्भर करता है। इस बीच, गतिशील विश्लेषण तकनीकें, जैसे स्मार्ट अनुबंध फ़ज़िंग (fuzzing) (opens in a new tab), सुरक्षा गुणों का उल्लंघन करने वाले संचालन का पता लगाने के लिए यादृच्छिक इनपुट मानों के साथ अनुबंध कोड निष्पादित करती हैं।
स्मार्ट अनुबंधों में सुरक्षा गुणों को सत्यापित करने के लिए औपचारिक सत्यापन एक अन्य तकनीक है। नियमित परीक्षण के विपरीत, औपचारिक सत्यापन निर्णायक रूप से एक स्मार्ट अनुबंध में त्रुटियों की अनुपस्थिति को साबित कर सकता है। यह एक औपचारिक विनिर्देश (formal specification) बनाकर प्राप्त किया जाता है जो वांछित सुरक्षा गुणों को कैप्चर करता है और यह साबित करता है कि अनुबंधों का एक औपचारिक मॉडल इस विनिर्देश का पालन करता है।
4. अपने कोड की स्वतंत्र समीक्षा के लिए पूछें
अपने अनुबंध का परीक्षण करने के बाद, दूसरों से किसी भी सुरक्षा समस्या के लिए स्रोत कोड की जांच करने के लिए कहना अच्छा है। परीक्षण एक स्मार्ट अनुबंध में हर खामी को उजागर नहीं करेगा, लेकिन एक स्वतंत्र समीक्षा प्राप्त करने से कमजोरियों को पहचानने की संभावना बढ़ जाती है।
ऑडिट
स्मार्ट अनुबंध ऑडिट शुरू करना एक स्वतंत्र कोड समीक्षा आयोजित करने का एक तरीका है। ऑडिटर यह सुनिश्चित करने में महत्वपूर्ण भूमिका निभाते हैं कि स्मार्ट अनुबंध सुरक्षित हैं और गुणवत्ता दोषों और डिज़ाइन त्रुटियों से मुक्त हैं।
इसके बावजूद, आपको ऑडिट को रामबाण (silver bullet) मानने से बचना चाहिए। स्मार्ट अनुबंध ऑडिट हर बग को नहीं पकड़ेंगे और ज्यादातर समीक्षाओं का एक अतिरिक्त दौर प्रदान करने के लिए डिज़ाइन किए गए हैं, जो प्रारंभिक विकास और परीक्षण के दौरान डेवलपर्स द्वारा छूटे गए मुद्दों का पता लगाने में मदद कर सकते हैं। स्मार्ट अनुबंध ऑडिट के लाभ को अधिकतम करने के लिए आपको ऑडिटर्स के साथ काम करने के लिए सर्वोत्तम प्रथाओं का भी पालन करना चाहिए, जैसे कि कोड का ठीक से दस्तावेजीकरण करना और इनलाइन टिप्पणियां जोड़ना।
- स्मार्ट अनुबंध ऑडिटिंग टिप्स और ट्रिक्स (opens in a new tab) - @tinchoabbate
- अपने ऑडिट का अधिकतम लाभ उठाएं (opens in a new tab) - Inference
बग बाउंटी
बग बाउंटी प्रोग्राम स्थापित करना बाहरी कोड समीक्षाओं को लागू करने का एक और दृष्टिकोण है। बग बाउंटी एक वित्तीय पुरस्कार है जो उन व्यक्तियों (आमतौर पर व्हाइटहैट हैकर्स) को दिया जाता है जो किसी एप्लिकेशन में कमजोरियों की खोज करते हैं।
जब ठीक से उपयोग किया जाता है, तो बग बाउंटी हैकर समुदाय के सदस्यों को महत्वपूर्ण खामियों के लिए आपके कोड का निरीक्षण करने के लिए प्रोत्साहन देती है। एक वास्तविक जीवन का उदाहरण “अनंत धन बग (infinite money bug)” है जो एक हमलावर को इथेरियम पर चलने वाले लेयर 2 (L2) प्रोटोकॉल, ऑप्टिमिज़्म (opens in a new tab) पर असीमित मात्रा में ईथर बनाने देता। सौभाग्य से, एक व्हाइटहैट हैकर ने खामी की खोज की (opens in a new tab) और टीम को सूचित किया, इस प्रक्रिया में एक बड़ा भुगतान अर्जित किया (opens in a new tab)।
एक उपयोगी रणनीति दांव पर लगे धन की मात्रा के अनुपात में बग बाउंटी प्रोग्राम का भुगतान निर्धारित करना है। “स्केलिंग बग बाउंटी (opens in a new tab)” के रूप में वर्णित, यह दृष्टिकोण व्यक्तियों को कमजोरियों का फायदा उठाने के बजाय जिम्मेदारी से उनका खुलासा करने के लिए वित्तीय प्रोत्साहन प्रदान करता है।
5. स्मार्ट अनुबंध विकास के दौरान सर्वोत्तम प्रथाओं का पालन करें
ऑडिट और बग बाउंटी का अस्तित्व आपको उच्च-गुणवत्ता वाला कोड लिखने की आपकी जिम्मेदारी से मुक्त नहीं करता है। अच्छी स्मार्ट अनुबंध सुरक्षा उचित डिज़ाइन और विकास प्रक्रियाओं का पालन करने से शुरू होती है:
-
सभी कोड को संस्करण नियंत्रण प्रणाली (version control system) में स्टोर करें, जैसे कि git
-
पुल अनुरोधों (pull requests) के माध्यम से सभी कोड संशोधन करें
-
सुनिश्चित करें कि पुल अनुरोधों में कम से कम एक स्वतंत्र समीक्षक हो—यदि आप किसी प्रोजेक्ट पर अकेले काम कर रहे हैं, तो अन्य डेवलपर्स को खोजने और कोड समीक्षाओं का व्यापार करने पर विचार करें
-
स्मार्ट अनुबंधों के परीक्षण, संकलन, और तैनाती के लिए एक विकास वातावरण (development environment) का उपयोग करें
-
अपने कोड को बुनियादी कोड विश्लेषण टूल, जैसे Cyfrin Aderyn (opens in a new tab), Mythril और स्लिथर के माध्यम से चलाएं। आदर्श रूप से, आपको प्रत्येक पुल अनुरोध के मर्ज होने से पहले ऐसा करना चाहिए और आउटपुट में अंतर की तुलना करनी चाहिए
-
सुनिश्चित करें कि आपका कोड बिना किसी त्रुटि के संकलित होता है, और Solidity कंपाइलर कोई चेतावनी नहीं देता है
-
अपने कोड का ठीक से दस्तावेजीकरण करें (NatSpec (opens in a new tab) का उपयोग करके) और अनुबंध वास्तुकला के बारे में विवरण को समझने में आसान भाषा में वर्णित करें। इससे दूसरों के लिए आपके कोड का ऑडिट और समीक्षा करना आसान हो जाएगा।
6. मजबूत आपदा रिकवरी योजनाएं लागू करें
सुरक्षित एक्सेस कंट्रोल डिज़ाइन करना, फ़ंक्शन संशोधक लागू करना, और अन्य सुझाव स्मार्ट अनुबंध सुरक्षा में सुधार कर सकते हैं, लेकिन वे दुर्भावनापूर्ण कारनामों की संभावना से इंकार नहीं कर सकते हैं। सुरक्षित स्मार्ट अनुबंध बनाने के लिए “विफलता की तैयारी” और हमलों का प्रभावी ढंग से जवाब देने के लिए एक फ़ॉलबैक योजना की आवश्यकता होती है। एक उचित आपदा रिकवरी योजना में निम्नलिखित में से कुछ या सभी घटक शामिल होंगे:
अनुबंध अपग्रेड
जबकि इथेरियम स्मार्ट अनुबंध डिफ़ॉल्ट रूप से अपरिवर्तनीय हैं, अपग्रेड पैटर्न का उपयोग करके कुछ हद तक परिवर्तनशीलता प्राप्त करना संभव है। उन मामलों में अनुबंधों को अपग्रेड करना आवश्यक है जहां एक महत्वपूर्ण खामी आपके पुराने अनुबंध को अनुपयोगी बना देती है और नया लॉजिक तैनात करना सबसे व्यवहार्य विकल्प है।
अनुबंध अपग्रेड तंत्र अलग तरह से काम करते हैं, लेकिन “प्रॉक्सी पैटर्न” स्मार्ट अनुबंधों को अपग्रेड करने के लिए अधिक लोकप्रिय दृष्टिकोणों में से एक है। प्रॉक्सी पैटर्न (opens in a new tab) किसी एप्लिकेशन की स्थिति और लॉजिक को दो अनुबंधों के बीच विभाजित करते हैं। पहला अनुबंध (जिसे 'प्रॉक्सी कॉन्ट्रैक्ट' कहा जाता है) स्थिति चर (जैसे, उपयोगकर्ता शेष) संग्रहीत करता है, जबकि दूसरा अनुबंध (जिसे 'लॉजिक अनुबंध' कहा जाता है) अनुबंध फ़ंक्शंस को निष्पादित करने के लिए कोड रखता है।
खाते प्रॉक्सी कॉन्ट्रैक्ट के साथ इंटरैक्ट करते हैं, जो delegatecall() (opens in a new tab) निम्न-स्तरीय कॉल का उपयोग करके सभी फ़ंक्शन कॉल को लॉजिक अनुबंध पर भेजता है। एक नियमित संदेश कॉल के विपरीत, delegatecall() यह सुनिश्चित करता है कि लॉजिक अनुबंध के पते पर चलने वाला कोड कॉलिंग अनुबंध के संदर्भ में निष्पादित हो। इसका मतलब है कि लॉजिक अनुबंध हमेशा प्रॉक्सी के स्टोरेज (अपने स्वयं के स्टोरेज के बजाय) में लिखेगा और msg.sender और msg.value के मूल मान संरक्षित रहेंगे।
लॉजिक अनुबंध को कॉल सौंपने के लिए प्रॉक्सी कॉन्ट्रैक्ट के स्टोरेज में इसका पता संग्रहीत करने की आवश्यकता होती है। इसलिए, अनुबंध के लॉजिक को अपग्रेड करना केवल एक और लॉजिक अनुबंध तैनात करने और प्रॉक्सी कॉन्ट्रैक्ट में नया पता संग्रहीत करने का मामला है। चूंकि प्रॉक्सी कॉन्ट्रैक्ट के बाद के कॉल स्वचालित रूप से नए लॉजिक अनुबंध पर रूट किए जाते हैं, इसलिए आपने वास्तव में कोड को संशोधित किए बिना अनुबंध को “अपग्रेड” कर लिया होगा।
अनुबंधों को अपग्रेड करने के बारे में अधिक जानकारी।
आपातकालीन रोक (Emergency stops)
जैसा कि उल्लेख किया गया है, व्यापक ऑडिटिंग और परीक्षण संभवतः एक स्मार्ट अनुबंध में सभी बग की खोज नहीं कर सकते हैं। यदि तैनाती के बाद आपके कोड में कोई भेद्यता दिखाई देती है, तो इसे पैच करना असंभव है क्योंकि आप अनुबंध पते पर चलने वाले कोड को नहीं बदल सकते हैं। इसके अलावा, अपग्रेड तंत्र (जैसे, प्रॉक्सी पैटर्न) को लागू करने में समय लग सकता है (उन्हें अक्सर विभिन्न पक्षों से अनुमोदन की आवश्यकता होती है), जो केवल हमलावरों को अधिक नुकसान पहुंचाने के लिए अधिक समय देता है।
परमाणु विकल्प (nuclear option) एक “आपातकालीन रोक” फ़ंक्शन को लागू करना है जो किसी अनुबंध में कमजोर फ़ंक्शंस के कॉल को अवरुद्ध करता है। आपातकालीन रोक में आमतौर पर निम्नलिखित घटक शामिल होते हैं:
-
एक वैश्विक बूलियन चर (global Boolean variable) जो यह दर्शाता है कि स्मार्ट अनुबंध रुकी हुई स्थिति में है या नहीं। अनुबंध सेट करते समय यह चर
falseपर सेट होता है, लेकिन अनुबंध बंद होने के बाद यहtrueपर वापस आ जाएगा। -
फ़ंक्शंस जो अपने निष्पादन में बूलियन चर को संदर्भित करते हैं। ऐसे फ़ंक्शंस तब सुलभ होते हैं जब स्मार्ट अनुबंध बंद नहीं होता है, और आपातकालीन रोक सुविधा चालू होने पर दुर्गम हो जाते हैं।
-
एक इकाई जिसकी आपातकालीन रोक फ़ंक्शन तक पहुंच है, जो बूलियन चर को
trueपर सेट करती है। दुर्भावनापूर्ण कार्यों को रोकने के लिए, इस फ़ंक्शन के कॉल को एक विश्वसनीय पते (जैसे, अनुबंध के मालिक) तक सीमित किया जा सकता है।
एक बार जब अनुबंध आपातकालीन रोक को सक्रिय कर देता है, तो कुछ फ़ंक्शंस कॉल करने योग्य नहीं होंगे। यह चुनिंदा फ़ंक्शंस को एक संशोधक में लपेटकर प्राप्त किया जाता है जो वैश्विक चर को संदर्भित करता है। नीचे एक उदाहरण (opens in a new tab) दिया गया है जो अनुबंधों में इस पैटर्न के कार्यान्वयन का वर्णन करता है:
// इस कोड का पेशेवर रूप से ऑडिट नहीं किया गया है और यह सुरक्षा या सटीकता के बारे में कोई वादा नहीं करता है। अपने जोखिम पर उपयोग करें।
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())। ऐसे फ़ंक्शंस स्थिति को हल करने में मदद कर सकते हैं, इसलिए उन्हें “प्रतिबंधित फ़ंक्शंस” सूची से बाहर रखा गया है।
आपातकालीन रोक कार्यक्षमता का उपयोग करना आपके स्मार्ट अनुबंध में गंभीर कमजोरियों से निपटने के लिए एक प्रभावी स्टॉपगैप प्रदान करता है। हालाँकि, यह उपयोगकर्ताओं के लिए डेवलपर्स पर भरोसा करने की आवश्यकता को बढ़ाता है कि वे इसे स्वार्थी कारणों से सक्रिय न करें। इस उद्देश्य के लिए, आपातकालीन रोक के नियंत्रण को विकेंद्रीकृत करना या तो इसे ऑनचेन वोटिंग तंत्र, टाइमलॉक, या मल्टीसिग वॉलेट से अनुमोदन के अधीन करके संभावित समाधान हैं।
घटना निगरानी (Event monitoring)
घटनाएँ (opens in a new tab) आपको स्मार्ट अनुबंध फ़ंक्शंस के कॉल को ट्रैक करने और स्थिति चर में परिवर्तनों की निगरानी करने की अनुमति देती हैं। जब भी कोई पक्ष सुरक्षा-महत्वपूर्ण कार्रवाई (जैसे, धन की निकासी) करता है, तो घटना उत्सर्जित करने के लिए अपने स्मार्ट अनुबंध को प्रोग्राम करना आदर्श है।
घटनाओं को लॉग करना और ऑफचेन उनकी निगरानी करना अनुबंध संचालन पर अंतर्दृष्टि प्रदान करता है और दुर्भावनापूर्ण कार्यों की तेजी से खोज में सहायता करता है। इसका मतलब है कि आपकी टीम हैक का तेजी से जवाब दे सकती है और उपयोगकर्ताओं पर प्रभाव को कम करने के लिए कार्रवाई कर सकती है, जैसे फ़ंक्शंस को रोकना या अपग्रेड करना।
आप एक ऑफ-द-शेल्फ मॉनिटरिंग टूल का विकल्प भी चुन सकते हैं जो जब भी कोई आपके अनुबंधों के साथ इंटरैक्ट करता है तो स्वचालित रूप से अलर्ट अग्रेषित करता है। ये टूल आपको विभिन्न ट्रिगर्स के आधार पर कस्टम अलर्ट बनाने की अनुमति देंगे, जैसे लेन-देन की मात्रा, फ़ंक्शन कॉल की आवृत्ति, या शामिल विशिष्ट फ़ंक्शंस। उदाहरण के लिए, आप एक अलर्ट प्रोग्राम कर सकते हैं जो तब आता है जब एक ही लेन-देन में निकाली गई राशि एक विशेष सीमा को पार कर जाती है।
7. सुरक्षित शासन प्रणाली डिज़ाइन करें
आप समुदाय के सदस्यों को मुख्य स्मार्ट अनुबंधों का नियंत्रण सौंपकर अपने एप्लिकेशन को विकेंद्रीकृत करना चाह सकते हैं। इस मामले में, स्मार्ट अनुबंध प्रणाली में एक शासन मॉड्यूल शामिल होगा—एक तंत्र जो समुदाय के सदस्यों को ऑनचेन शासन प्रणाली के माध्यम से प्रशासनिक कार्यों को स्वीकृति देने की अनुमति देता है। उदाहरण के लिए, एक प्रॉक्सी कॉन्ट्रैक्ट को नए कार्यान्वयन में अपग्रेड करने के प्रस्ताव पर टोकन-धारकों द्वारा वोट किया जा सकता है।
विकेंद्रीकृत शासन फायदेमंद हो सकता है, खासकर क्योंकि यह डेवलपर्स और अंतिम-उपयोगकर्ताओं के हितों को संरेखित करता है। फिर भी, यदि गलत तरीके से लागू किया जाता है तो स्मार्ट अनुबंध शासन तंत्र नए जोखिम पेश कर सकते हैं। एक प्रशंसनीय परिदृश्य यह है कि यदि कोई हमलावर फ्लैश ऋण लेकर भारी मतदान शक्ति (रखे गए टोकन की संख्या में मापा गया) प्राप्त करता है और एक दुर्भावनापूर्ण प्रस्ताव को आगे बढ़ाता है।
ऑनचेन शासन से संबंधित समस्याओं को रोकने का एक तरीका टाइमलॉक का उपयोग करना (opens in a new tab) है। एक टाइमलॉक एक स्मार्ट अनुबंध को कुछ कार्यों को निष्पादित करने से रोकता है जब तक कि एक विशिष्ट समय बीत न जाए। अन्य रणनीतियों में प्रत्येक टोकन को इस आधार पर “वोटिंग वेट (voting weight)” सौंपना शामिल है कि इसे कितने समय के लिए लॉक किया गया है, या वर्तमान ब्लॉक के बजाय ऐतिहासिक अवधि (उदाहरण के लिए, अतीत में 2-3 ब्लॉक) में किसी पते की मतदान शक्ति को मापना शामिल है। दोनों तरीके ऑनचेन वोटों को स्विंग करने के लिए जल्दी से मतदान शक्ति इकट्ठा करने की संभावना को कम करते हैं।
साझा किए गए लिंक में सुरक्षित शासन प्रणाली डिज़ाइन करने (opens in a new tab), DAO में विभिन्न मतदान तंत्र (opens in a new tab), और DeFi का लाभ उठाने वाले सामान्य DAO हमले वैक्टर (opens in a new tab) के बारे में अधिक जानकारी।
8. कोड में जटिलता को न्यूनतम करें
पारंपरिक सॉफ्टवेयर डेवलपर KISS (“keep it simple, stupid”) सिद्धांत से परिचित हैं, जो सॉफ्टवेयर डिज़ाइन में अनावश्यक जटिलता पेश करने के खिलाफ सलाह देता है। यह लंबे समय से चली आ रही सोच का अनुसरण करता है कि “जटिल प्रणालियाँ जटिल तरीकों से विफल होती हैं” और महंगी त्रुटियों के प्रति अधिक संवेदनशील होती हैं।
स्मार्ट अनुबंध लिखते समय चीजों को सरल रखना विशेष महत्व का है, यह देखते हुए कि स्मार्ट अनुबंध संभावित रूप से बड़ी मात्रा में मूल्य को नियंत्रित कर रहे हैं। स्मार्ट अनुबंध लिखते समय सरलता प्राप्त करने के लिए एक टिप मौजूदा लाइब्रेरी का पुन: उपयोग करना है, जैसे कि ओपनजेपेलिन अनुबंध (opens in a new tab), जहां संभव हो। क्योंकि इन लाइब्रेरी का डेवलपर्स द्वारा बड़े पैमाने पर ऑडिट और परीक्षण किया गया है, इसलिए उनका उपयोग करने से खरोंच से नई कार्यक्षमता लिखकर बग पेश करने की संभावना कम हो जाती है।
एक और आम सलाह छोटे फ़ंक्शंस लिखना और कई अनुबंधों में व्यावसायिक लॉजिक को विभाजित करके अनुबंधों को मॉड्यूलर रखना है। सरल कोड लिखने से न केवल एक स्मार्ट अनुबंध में हमले की सतह कम हो जाती है, बल्कि समग्र प्रणाली की शुद्धता के बारे में तर्क करना और संभावित डिज़ाइन त्रुटियों का जल्दी पता लगाना भी आसान हो जाता है।
9. सामान्य स्मार्ट अनुबंध कमजोरियों से बचाव करें
पुन:प्रवेश (Reentrancy)
EVM समवर्ती (concurrency) की अनुमति नहीं देता है, जिसका अर्थ है कि संदेश कॉल में शामिल दो अनुबंध एक साथ नहीं चल सकते हैं। एक बाहरी कॉल कॉलिंग अनुबंध के निष्पादन और मेमोरी को तब तक रोक देता है जब तक कि कॉल वापस नहीं आ जाती, जिस बिंदु पर निष्पादन सामान्य रूप से आगे बढ़ता है। इस प्रक्रिया को औपचारिक रूप से किसी अन्य अनुबंध में नियंत्रण प्रवाह (control flow) (opens in a new tab) स्थानांतरित करने के रूप में वर्णित किया जा सकता है।
हालांकि ज्यादातर हानिरहित, अविश्वसनीय अनुबंधों में नियंत्रण प्रवाह को स्थानांतरित करने से पुन:प्रवेश जैसी समस्याएं हो सकती हैं। पुन:प्रवेश हमला तब होता है जब कोई दुर्भावनापूर्ण अनुबंध मूल फ़ंक्शन आमंत्रण पूरा होने से पहले किसी असुरक्षित अनुबंध में वापस कॉल करता है। इस प्रकार के हमले को एक उदाहरण के साथ सबसे अच्छी तरह समझाया गया है।
एक साधारण स्मार्ट अनुबंध ('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 हैक (opens in a new tab) में हुआ था। पुन:प्रवेश हमले आज भी स्मार्ट अनुबंधों के लिए एक महत्वपूर्ण मुद्दा हैं जैसा कि पुन:प्रवेश कारनामों की सार्वजनिक सूची (opens in a new tab) दिखाती है।
पुन:प्रवेश हमलों को कैसे रोकें
पुन:प्रवेश से निपटने का एक दृष्टिकोण checks-effects-interactions पैटर्न (opens in a new tab) का पालन करना है। यह पैटर्न फ़ंक्शंस के निष्पादन को इस तरह से आदेश देता है कि निष्पादन के साथ आगे बढ़ने से पहले आवश्यक जांच करने वाला कोड पहले आता है, उसके बाद अनुबंध की स्थिति में हेरफेर करने वाला कोड आता है, और अन्य अनुबंधों या 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) (opens in a new tab) प्रणाली का भी उपयोग कर सकते हैं जिसके लिए उपयोगकर्ताओं को स्मार्ट अनुबंधों से धन निकालने की आवश्यकता होती है, बजाय "पुश भुगतान (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 (opens in a new tab)) का उपयोग करना चाहिए जो अंडरफ़्लो/ओवरफ़्लो की जांच करती है।
ऑरेकल हेरफेर
ऑरेकल ऑफचेन जानकारी प्राप्त करते हैं और इसे स्मार्ट अनुबंधों के उपयोग के लिए ऑनचेन भेजते हैं। ऑरेकल के साथ, आप ऐसे स्मार्ट अनुबंध डिज़ाइन कर सकते हैं जो ऑफचेन सिस्टम, जैसे पूंजी बाजार, के साथ इंटरऑपरेट करते हैं, जिससे उनके एप्लिकेशन का काफी विस्तार होता है।
लेकिन अगर ऑरेकल दूषित हो जाता है और ऑनचेन गलत जानकारी भेजता है, तो स्मार्ट अनुबंध गलत इनपुट के आधार पर निष्पादित होंगे, जिससे समस्याएँ हो सकती हैं। यह “ओरेकल समस्या” का आधार है, जो यह सुनिश्चित करने के कार्य से संबंधित है कि ब्लॉकचेन ओरेकल से जानकारी सटीक, अद्यतित और समय पर हो।
एक संबंधित सुरक्षा चिंता किसी संपत्ति के लिए स्पॉट मूल्य प्राप्त करने के लिए ऑनचेन ऑरेकल, जैसे विकेंद्रीकृत एक्सचेंज, का उपयोग करना है। विकेंद्रीकृत वित्त (DeFi) उद्योग में ऋण देने वाले प्लेटफ़ॉर्म अक्सर उपयोगकर्ता के संपार्श्विक के मूल्य को निर्धारित करने के लिए ऐसा करते हैं ताकि यह निर्धारित किया जा सके कि वे कितना उधार ले सकते हैं।
DEX कीमतें अक्सर सटीक होती हैं, जिसका मुख्य कारण आर्बिट्रेजर्स (arbitrageurs) द्वारा बाजारों में समानता बहाल करना है। हालाँकि, वे हेरफेर के लिए खुले हैं, खासकर यदि ऑनचेन ऑरेकल ऐतिहासिक ट्रेडिंग पैटर्न के आधार पर संपत्ति की कीमतों की गणना करता है (जैसा कि आमतौर पर होता है)।
उदाहरण के लिए, एक हमलावर आपके ऋण देने वाले अनुबंध के साथ इंटरैक्ट करने से ठीक पहले फ्लैश ऋण लेकर कृत्रिम रूप से किसी संपत्ति के स्पॉट मूल्य को बढ़ा सकता है। संपत्ति की कीमत के लिए DEX से पूछताछ करने पर सामान्य से अधिक मूल्य वापस आएगा (हमलावर के बड़े “खरीद आदेश (buy order)” के कारण संपत्ति की मांग में वृद्धि), जिससे उन्हें अपनी क्षमता से अधिक उधार लेने की अनुमति मिलेगी। इस तरह के "फ्लैश ऋण हमलों" का उपयोग DeFi एप्लिकेशनों के बीच मूल्य ऑरेकल पर निर्भरता का फायदा उठाने के लिए किया गया है, जिससे प्रोटोकॉल को लाखों का नुकसान हुआ है।
ऑरेकल हेरफेर को कैसे रोकें
ऑरेकल हेरफेर से बचने (opens in a new tab) के लिए न्यूनतम आवश्यकता एक विकेंद्रीकृत ऑरेकल नेटवर्क का उपयोग करना है जो विफलता के एकल बिंदुओं से बचने के लिए कई स्रोतों से जानकारी प्राप्त करता है। ज्यादातर मामलों में, विकेंद्रीकृत ऑरेकल में ऑरेकल नोड्स को सही जानकारी रिपोर्ट करने के लिए प्रोत्साहित करने के लिए अंतर्निहित क्रिप्टोइकोनॉमिक प्रोत्साहन होते हैं, जिससे वे केंद्रीकृत ऑरेकल की तुलना में अधिक सुरक्षित हो जाते हैं।
यदि आप संपत्ति की कीमतों के लिए ऑनचेन ऑरेकल से पूछताछ करने की योजना बना रहे हैं, तो ऐसे ऑरेकल का उपयोग करने पर विचार करें जो समय-भारित औसत मूल्य (time-weighted average price - TWAP) तंत्र लागू करता है। एक TWAP ऑरेकल (opens in a new tab) दो अलग-अलग समय बिंदुओं (जिन्हें आप संशोधित कर सकते हैं) पर किसी संपत्ति की कीमत पूछता है और प्राप्त औसत के आधार पर स्पॉट मूल्य की गणना करता है। लंबी समयावधि चुनना आपके प्रोटोकॉल को मूल्य हेरफेर से बचाता है क्योंकि हाल ही में निष्पादित बड़े आदेश संपत्ति की कीमतों को प्रभावित नहीं कर सकते हैं।
## डेवलपर्स के लिए स्मार्ट अनुबंध सुरक्षा संसाधन
### स्मार्ट अनुबंधों का विश्लेषण करने और कोड की शुद्धता को सत्यापित करने के लिए टूल
- **[परीक्षण टूल और लाइब्रेरी](/developers/docs/smart-contracts/testing/#testing-tools-and-libraries)** - _स्मार्ट अनुबंधों पर यूनिट परीक्षण, स्थिर विश्लेषण और गतिशील विश्लेषण करने के लिए उद्योग-मानक टूल और लाइब्रेरी का संग्रह।_
- **[औपचारिक सत्यापन टूल](/developers/docs/smart-contracts/formal-verification/#formal-verification-tools)** - _स्मार्ट अनुबंधों में कार्यात्मक शुद्धता को सत्यापित करने और इनवेरिएंट्स की जांच करने के लिए टूल।_
- **[स्मार्ट अनुबंध ऑडिटिंग सेवाएँ](/developers/docs/smart-contracts/testing/#smart-contract-auditing-services)** - _इथेरियम विकास परियोजनाओं के लिए स्मार्ट अनुबंध ऑडिटिंग सेवाएँ प्रदान करने वाले संगठनों की सूची।_
- **[बग बाउंटी प्लेटफ़ॉर्म](/developers/docs/smart-contracts/testing/#bug-bounty-platforms)** - _बग बाउंटी का समन्वय करने और स्मार्ट अनुबंधों में महत्वपूर्ण कमजोरियों के जिम्मेदार प्रकटीकरण को पुरस्कृत करने के लिए प्लेटफ़ॉर्म।_
- **[Fork Checker](https://forkchecker.hashex.org/)** - _फ़ोर्क किए गए अनुबंध के संबंध में सभी उपलब्ध जानकारी की जांच करने के लिए एक मुफ़्त ऑनलाइन टूल।_
- **[ABI Encoder](https://abi.hashex.org/)** - _आपके Solidity अनुबंध फ़ंक्शंस और कंस्ट्रक्टर तर्कों को एन्कोड करने के लिए एक मुफ़्त ऑनलाइन सेवा।_
- **[Aderyn](https://github.com/Cyfrin/aderyn)** - _Solidity स्टेटिक एनालाइज़र, जो संदिग्ध कमजोरियों का पता लगाने के लिए एब्सट्रैक्ट सिंटैक्स ट्री (AST) को पार करता है और आसानी से पढ़े जाने वाले मार्कडाउन प्रारूप में समस्याओं को प्रिंट करता है।_
### स्मार्ट अनुबंधों की निगरानी के लिए टूल
- **[Tenderly Real-Time Alerting](https://tenderly.co/monitoring)** - _आपके स्मार्ट अनुबंधों या वॉलेट पर असामान्य या अप्रत्याशित घटनाएँ होने पर रीयल-टाइम सूचनाएं प्राप्त करने के लिए एक टूल।_
### स्मार्ट अनुबंधों के सुरक्षित प्रशासन के लिए टूल
- **[Safe](https://safe.global/)** - _इथेरियम पर चलने वाला स्मार्ट अनुबंध वॉलेट जिसे किसी लेन-देन के होने से पहले उसे स्वीकृति देने के लिए न्यूनतम संख्या में लोगों की आवश्यकता होती है (M-of-N)।_
- **[ओपनजेपेलिन अनुबंध](https://docs.openzeppelin.com/contracts/5.x/)** - _अनुबंध स्वामित्व, अपग्रेड, एक्सेस नियंत्रण, शासन, पॉज़ेबिलिटी और बहुत कुछ सहित प्रशासनिक सुविधाओं को लागू करने के लिए अनुबंध लाइब्रेरी।_
### स्मार्ट अनुबंध ऑडिटिंग सेवाएँ
- **[कॉन्सेन्सिस डिलिजेंस](https://diligence.consensys.io/)** - _स्मार्ट अनुबंध ऑडिटिंग सेवा जो ब्लॉकचेन इकोसिस्टम में परियोजनाओं को यह सुनिश्चित करने में मदद करती है कि उनके प्रोटोकॉल लॉन्च के लिए तैयार हैं और उपयोगकर्ताओं की सुरक्षा के लिए बनाए गए हैं।_
- **[CertiK](https://www.certik.com/)** - _ब्लॉकचेन सुरक्षा फर्म जो स्मार्ट अनुबंधों और ब्लॉकचेन नेटवर्क पर अत्याधुनिक औपचारिक सत्यापन तकनीक के उपयोग में अग्रणी है।_
- **[Trail of Bits](https://www.trailofbits.com/)** - _साइबर सुरक्षा कंपनी जो जोखिम को कम करने और कोड को मजबूत करने के लिए हमलावर मानसिकता के साथ सुरक्षा अनुसंधान को जोड़ती है।_
- **[PeckShield](https://peckshield.com/)** - _ब्लॉकचेन सुरक्षा कंपनी जो संपूर्ण ब्लॉकचेन इकोसिस्टम की सुरक्षा, गोपनीयता और उपयोगिता के लिए उत्पाद और सेवाएँ प्रदान करती है।_
- **[QuantStamp](https://quantstamp.com/)** - _ऑडिटिंग सेवा जो सुरक्षा और जोखिम मूल्यांकन सेवाओं के माध्यम से ब्लॉकचेन तकनीक को मुख्यधारा में अपनाने की सुविधा प्रदान करती है।_
- **[ओपनजेपेलिन](https://www.openzeppelin.com/security-audits)** - _स्मार्ट अनुबंध सुरक्षा कंपनी जो वितरित प्रणालियों के लिए सुरक्षा ऑडिट प्रदान करती है।_
- **[Runtime Verification](https://runtimeverification.com/)** - _सुरक्षा कंपनी जो स्मार्ट अनुबंधों के औपचारिक मॉडलिंग और सत्यापन में विशेषज्ञता रखती है।_
- **[Hacken](https://hacken.io)** - _Web3 साइबर सुरक्षा ऑडिटर जो ब्लॉकचेन सुरक्षा के लिए 360-डिग्री दृष्टिकोण लाता है।_
- **[नेदरमाइंड](https://www.nethermind.io/smart-contract-audits)** - _Solidity और Cairo ऑडिटिंग सेवाएँ, जो इथेरियम और स्टार्कनेट पर स्मार्ट अनुबंधों की अखंडता और उपयोगकर्ताओं की सुरक्षा सुनिश्चित करती हैं।_
- **[HashEx](https://hashex.org/)** - _HashEx क्रिप्टोकरेंसी की सुरक्षा सुनिश्चित करने के लिए ब्लॉकचेन और स्मार्ट अनुबंध ऑडिटिंग पर ध्यान केंद्रित करता है, जो स्मार्ट अनुबंध विकास, पेनेट्रेशन परीक्षण, ब्लॉकचेन परामर्श जैसी सेवाएँ प्रदान करता है।_
- **[Code4rena](https://code4rena.com/)** - _प्रतिस्पर्धी ऑडिट प्लेटफ़ॉर्म जो स्मार्ट अनुबंध सुरक्षा विशेषज्ञों को कमजोरियों को खोजने और Web3 को अधिक सुरक्षित बनाने में मदद करने के लिए प्रोत्साहित करता है।_
- **[CodeHawks](https://codehawks.com/)** - _प्रतिस्पर्धी ऑडिट प्लेटफ़ॉर्म जो सुरक्षा शोधकर्ताओं के लिए स्मार्ट अनुबंध ऑडिटिंग प्रतियोगिताओं की मेजबानी करता है।_
- **[Cyfrin](https://cyfrin.io)** - _Web3 सुरक्षा पावरहाउस, जो उत्पादों और स्मार्ट अनुबंध ऑडिटिंग सेवाओं के माध्यम से क्रिप्टो सुरक्षा को विकसित करता है।_
- **[ImmuneBytes](https://immunebytes.com/smart-contract-audit/)** - _Web3 सुरक्षा फर्म जो अनुभवी ऑडिटरों की एक टीम और सर्वश्रेष्ठ-इन-क्लास टूल के माध्यम से ब्लॉकचेन सिस्टम के लिए सुरक्षा ऑडिट प्रदान करती है।_
- **[Oxorio](https://oxor.io/)** - _क्रिप्टो फर्मों और विकेंद्रीकृत वित्त (DeFi) परियोजनाओं के लिए EVM, Solidity, ZK, क्रॉस-चेन तकनीक में विशेषज्ञता के साथ स्मार्ट अनुबंध ऑडिट और ब्लॉकचेन सुरक्षा सेवाएँ।_
- **[Inference](https://inference.ag/)** - _सुरक्षा ऑडिटिंग कंपनी, जो EVM-आधारित ब्लॉकचेन के लिए स्मार्ट अनुबंध ऑडिटिंग में विशेषज्ञता रखती है। इसके विशेषज्ञ ऑडिटरों की बदौलत वे संभावित समस्याओं की पहचान करते हैं और तैनाती से पहले उन्हें ठीक करने के लिए कार्रवाई योग्य समाधान सुझाते हैं।_
### बग बाउंटी प्लेटफ़ॉर्म
- **[Immunefi](https://immunefi.com/)** - _स्मार्ट अनुबंधों और विकेंद्रीकृत वित्त (DeFi) परियोजनाओं के लिए बग बाउंटी प्लेटफ़ॉर्म, जहाँ सुरक्षा शोधकर्ता कोड की समीक्षा करते हैं, कमजोरियों का खुलासा करते हैं, भुगतान प्राप्त करते हैं और क्रिप्टो को अधिक सुरक्षित बनाते हैं।_
- **[HackerOne](https://www.hackerone.com/)** - _भेद्यता समन्वय और बग बाउंटी प्लेटफ़ॉर्म जो व्यवसायों को पेनेट्रेशन परीक्षकों और साइबर सुरक्षा शोधकर्ताओं से जोड़ता है।_
- **[HackenProof](https://hackenproof.com/)** - _क्रिप्टो परियोजनाओं (विकेंद्रीकृत वित्त (DeFi), स्मार्ट अनुबंध, वॉलेट, CEX और बहुत कुछ) के लिए विशेषज्ञ बग बाउंटी प्लेटफ़ॉर्म, जहाँ सुरक्षा पेशेवर ट्राइएज सेवाएँ प्रदान करते हैं और शोधकर्ताओं को प्रासंगिक, सत्यापित बग रिपोर्ट के लिए भुगतान मिलता है।_
- **[Sherlock](https://www.sherlock.xyz/)** - _स्मार्ट अनुबंध सुरक्षा के लिए Web3 में अंडरराइटर, जहाँ ऑडिटरों के लिए भुगतान स्मार्ट अनुबंधों के माध्यम से प्रबंधित किया जाता है ताकि यह सुनिश्चित किया जा सके कि प्रासंगिक बग्स के लिए उचित भुगतान किया जाए।_
- **[CodeHawks](https://www.codehawks.com/)** - _प्रतिस्पर्धी बग बाउंटी प्लेटफ़ॉर्म जहाँ ऑडिटर सुरक्षा प्रतियोगिताओं और चुनौतियों में भाग लेते हैं, और (जल्द ही) अपने स्वयं के निजी ऑडिट में भी।_
### ज्ञात स्मार्ट अनुबंध कमजोरियों और कारनामों (exploits) के प्रकाशन
- **[कॉन्सेन्सिस: स्मार्ट अनुबंध ज्ञात हमले](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/)** - _अधिकांश मामलों के लिए नमूना कोड के साथ, सबसे महत्वपूर्ण अनुबंध कमजोरियों का शुरुआती-अनुकूल स्पष्टीकरण।_
- **[SWC Registry](https://swcregistry.io/)** - _कॉमन वीकनेस एन्यूमरेशन (CWE) आइटम की क्यूरेटेड सूची जो इथेरियम स्मार्ट अनुबंधों पर लागू होती है।_
- **[Rekt](https://rekt.news/)** - _विस्तृत पोस्टमार्टम रिपोर्ट के साथ हाई-प्रोफाइल क्रिप्टो हैक्स और कारनामों का नियमित रूप से अपडेट किया जाने वाला प्रकाशन।_
### स्मार्ट अनुबंध सुरक्षा सीखने के लिए चुनौतियाँ
- **[Awesome BlockSec CTF](https://github.com/blockthreat/blocksec-ctfs)** - _ब्लॉकचेन सुरक्षा वॉरगेम्स, चुनौतियों और [कैप्चर द फ्लैग](https://www.webopedia.com/definitions/ctf-event/amp/) प्रतियोगिताओं और समाधान राइटअप की क्यूरेटेड सूची।_
- **[Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/)** - _विकेंद्रीकृत वित्त (DeFi) स्मार्ट अनुबंधों की आक्रामक सुरक्षा सीखने और बग-हंटिंग और सुरक्षा ऑडिटिंग में कौशल बनाने के लिए वॉरगेम।_
- **[Ethernaut](https://ethernaut.openzeppelin.com/)** - _Web3/Solidity-आधारित वॉरगेम जहाँ प्रत्येक स्तर एक स्मार्ट अनुबंध है जिसे 'हैक' करने की आवश्यकता होती है।_
- **[HackenProof x HackTheBox](https://app.hackthebox.com/tracks/HackenProof-Track)** - _एक फंतासी साहसिक कार्य में सेट की गई स्मार्ट अनुबंध हैकिंग चुनौती। चुनौती को सफलतापूर्वक पूरा करने से एक निजी बग बाउंटी प्रोग्राम तक पहुंच भी मिलती है।_
### स्मार्ट अनुबंधों को सुरक्षित करने के लिए सर्वोत्तम अभ्यास
- **[कॉन्सेन्सिस: इथेरियम स्मार्ट अनुबंध सुरक्षा सर्वोत्तम अभ्यास](https://consensys.github.io/smart-contract-best-practices/)** - _इथेरियम स्मार्ट अनुबंधों को सुरक्षित करने के लिए दिशानिर्देशों की व्यापक सूची।_
- **[Nascent: Simple Security Toolkit](https://github.com/nascentxyz/simple-security-toolkit)** - _स्मार्ट अनुबंध विकास के लिए व्यावहारिक सुरक्षा-केंद्रित गाइड और चेकलिस्ट का संग्रह।_
- **[Solidity Patterns](https://fravoll.github.io/solidity-patterns/)** - _स्मार्ट अनुबंध प्रोग्रामिंग भाषा Solidity के लिए सुरक्षित पैटर्न और सर्वोत्तम प्रथाओं का उपयोगी संकलन।_
- **[Solidity Docs: Security Considerations](https://docs.soliditylang.org/en/v0.8.16/security-considerations.html)** - _Solidity के साथ सुरक्षित स्मार्ट अनुबंध लिखने के लिए दिशानिर्देश।_
- **[स्मार्ट अनुबंध सुरक्षा सत्यापन मानक](https://github.com/securing/SCSVS)** - _डेवलपर्स, आर्किटेक्ट्स, सुरक्षा समीक्षकों और विक्रेताओं के लिए स्मार्ट अनुबंधों की सुरक्षा को मानकीकृत करने के लिए बनाई गई चौदह-भाग की चेकलिस्ट।_
- **[स्मार्ट अनुबंध सुरक्षा और ऑडिटिंग सीखें](https://updraft.cyfrin.io/courses/security)** - _अंतिम स्मार्ट अनुबंध सुरक्षा और ऑडिटिंग कोर्स, जो उन स्मार्ट अनुबंध डेवलपर्स के लिए बनाया गया है जो अपनी सुरक्षा सर्वोत्तम प्रथाओं को बेहतर बनाना चाहते हैं और सुरक्षा शोधकर्ता बनना चाहते हैं।_
### स्मार्ट अनुबंध सुरक्षा पर ट्यूटोरियल
- [सुरक्षित स्मार्ट अनुबंध कैसे लिखें](/developers/tutorials/secure-development-workflow/)
- [स्मार्ट अनुबंध बग खोजने के लिए स्लिथर का उपयोग कैसे करें](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/)
- [स्मार्ट अनुबंध बग खोजने के लिए मैन्टिकोर का उपयोग कैसे करें](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/)
- [स्मार्ट अनुबंध सुरक्षा दिशानिर्देश](/developers/tutorials/smart-contract-security-guidelines/)
- [अपने टोकन अनुबंध को मनमाने टोकन के साथ सुरक्षित रूप से कैसे एकीकृत करें](/developers/tutorials/token-integration-checklist/)
- [Cyfrin Updraft - स्मार्ट अनुबंध सुरक्षा और ऑडिटिंग पूर्ण कोर्स](https://updraft.cyfrin.io/courses/security)