انواع آسیب پذیری های رایج قراردادهای هوشمند و نحوه جلوگیری از آن ها
چکیده
قراردادهای هوشمند دنیای دیجیتال را دچار تحول کرده و راه جدیدی را برای ایجاد توافقات بدون نیاز به اعتماد و خودکار ارائه کرده است. این قراردادهای خوداجرا که در شبکههای بلاک چین مانند اتریوم کدگذاری شدهاند، در همه چیز از تراکنشهای مالی گرفته تا مدیریت زنجیره تامین استفاده میشوند. با این حال، قراردادهای هوشمند بیخطر نیستند. آنها مجموعهای از آسیب پذیریهای خاص خود را دارند که اگر به درستی مورد توجه قرار نگیرد، میتوان از آنها سوء استفاده کرد. این مقاله به بررسی رایجترین آسیبپذیریهای قراردادهای هوشمند و نحوه جلوگیری از آنها میپردازد و به گونهای توضیح داده میشود که برای کسانی هم که ممکن است به این فناوری آشنا نباشند، قابل درک باشد.
درک قراردادهای هوشمند
قبل از اینکه به آسیبپذیریها بپردازیم، اجازه دهید سریعاً قراردادهای هوشمند را مرور کنیم. یک ماشین خودکار را تصور کنید. در آن پول میگذارید، محصولی را انتخاب میکنید و اگر همه چیز مرتب باشد، میان وعده خود را دریافت میکنید و نیازی به دخالت انسانی نیست. قراردادهای هوشمند به طور مشابه اما با تراکنشهای دیجیتال کار میکنند. آنها به طور خودکار اقدامات را در صورت برآورده شدن شرایط خاص انجام میدهند. این اتوماسیون را میتوان برای هر چیزی از انتقال ارزهای دیجیتال تا اجرای قراردادهای قانونی استفاده کرد.
تاریخچه قراردادهای هوشمند
مفهوم قراردادهای هوشمند اولین بار توسط نیک سابو (Nick Szabo)، دانشمند کامپیوتر، محقق و رمزنگار، در اوایل دهه ۱۹۹۰ معرفی شد. چشمانداز سابو ایجاد راهی برای رسمی و ایمن کردن توافقات در شبکههای دیجیتال بدون اتکا به شخص ثالث قابل اعتماد بود. او قراردادهای هوشمند را به عنوان قراردادهای خوداجرا با شرایطی که مستقیماً در کد نوشته شده است، توصیف کرد که مشابه ماشینهای فروش خودکار است که بهطور خودکار محصولات را پس از دریافت پرداخت، توزیع میکنند.
علیرغم ایدههای پیشگام سابو، فناوری و زیرساخت مورد نیاز برای اجرای قراردادهای هوشمند در آن زمان هنوز در دسترس نبود. تا اینکه ظهور فناوری بلاک چین با راه اندازی بیت کوین در سال ۲۰۰۹ بود که پتانسیل قراردادهای هوشمند شروع به تحقق یافت. با این حال، زبان اسکریپت بیت کوین محدود بود و اساساً برای تراکنشهای ساده طراحی شده بود و پیچیدگی لازم برای قراردادهای هوشمند تمام عیار را نداشت.
این پیشرفت در سال ۲۰۱۵ با راهاندازی اتریوم، یک پلتفرم غیرمتمرکز که به طور خاص برای پشتیبانی از قراردادهای هوشمند و برنامههای کاربردی غیرمتمرکز (DApps) طراحی شده بود، رخ داد. اتریوم که توسط ویتالیک بوترین ایجاد شد، یک زبان برنامه نویسی قوی و کامل به نام سالیدیتی (Solidity) را معرفی کرد که به توسعهدهندگان این امکان را میدهد تا قراردادهای هوشمند پیچیده بنویسند و آنها را به کار گیرند. این نوآوری در را برای پذیرش گسترده و موارد استفاده در صنایع مختلف، از امور مالی گرفته تا مدیریت زنجیره تامین، باز کرد و نقطه عطفی در تاریخ قراردادهای هوشمند را رقم زد. همچنین امروزه بسیاری از صرافیهای ارز دیجیتال از این حملات برای بهبود امنیت استفاده میکنند تا کاربران با خیال راحت خرید ارز دیجیتال انجام دهند.
آسیب پذیری های رایج در قراردادهای هوشمند
۱. حملات ورود مجدد (Reentrancy Attacks)
حمله ورود مجدد مانند این است که کسی مواد خوراکی اضافی را بدون پرداخت پول بیشتر دزدکی برمیدارد. این مورد زمانی اتفاق میافتد که یک قرارداد هوشمند، یک قرارداد خارجی را فراخوانی میکند و آن قرارداد خارجی میتواند قبل از اتمام اجرای قرارداد، دوباره آن را به قرارداد اصلی فراخوانی کند. این مورد میتواند منجر به دستکاری وضعیت قرارداد به روشهای غیرمنتظره شود که اغلب منجر به سرقت وجوه میشود.
البته اصل این موضوعات، حملات و آسیبپذیریها به صورت کدنویسی هستند و نیازمند تخصص بوده ولی در این مقاله ما تنها به توضیح مختصر و سادهای از آنها میپردازیم ولی اگر علاقه خاصی به این سبک محتوا دارید میتوانید نظرات خود را بیان کنید تا به صورت عمیقتر همراه با کدنویسی اصلی سالیدیتی خدمت شما عزیزان مقالهای را تهیه کنیم.
نحوه جلوگیری از این نوع حمله:
– الگوی چکها، اثرات، تعاملات: همیشه قبل از فراخوانی قرارداد خارجی، وضعیت قرارداد را به روز کنید.
– گاردهای ورود مجدد: قفلی را اجرا کنید که تا زمانی که عملکرد کامل نشده است از ورود مجدد جلوگیری میکند.
۲. سرریز و آندرفلو عدد صحیح (Overflow and Underflow)
تصور کنید اگر حساب بانکی شما میتوانست به گونهای شود که با برداشت یک دلار دیگر در زمانی که موجودی شما صفر است، ناگهان یک میلیارد دلار به شما میرسید. این همان چیزی است که با سرریز و آندرفلو اعداد صحیح در قراردادهای هوشمند اتفاق میافتد. هنگامی که اعداد از حداکثر یا حداقل حد خود فراتر میروند، میتوانند به هم برسند و باعث اشتباهات جدی در محاسبات شوند.
نحوه جلوگیری از این نوع حمله:
– کتابخانه SafeMath: این کتابخانهها توابعی را ارائه میکنند که سرریزها و آندرفلو را بررسی کرده و از وقوع آنها جلوگیری میکنند.
– انواع دادههای مناسب: از انواع دادهای استفاده کنید که بتواند محدوده مورد انتظار مقادیر را مدیریت کند.
البته در ورژنهای جدید سالیدیتی این مسئله به صورت اتوماتیک حل شده ولی بهتر است خودتان دوباره چک کنید.
۳. فراخوانی مقدار برگشتی (Call Return Value)
وقتی ایمیلی ارسال میکنید، معمولاً اعلان «پیام ارسال شده» را بررسی کرده تا مطمئن شوید که ایمیل ارسال شده است. به طور مشابه، هنگامی که یک قرارداد هوشمند با یک قرارداد خارجی فراخوانی انجام میدهد، باید بررسی کند که آیا فراخوانی موفق بوده است یا خیر. عدم انجام این کار میتواند منجر به از دست دادن سرمایه یا سایر رفتارهای ناخواسته شود.
نحوه جلوگیری از این حمله:
-بررسی مقادیر برگشتی: همیشه مقدار برگشتی یک تماس خارجی را بررسی کنید.
– از تابع require استفاده کنید: با استفاده از بررسی که اجرا را متوقف میکند، مطمئن شوید که فراخوانی موفق بوده است.
۴. انکار سرویس (DoS)
حمله انکار سرویس مانند کسی است که یک دستگاه فروش خودکار را دچار پارازیت میکند تا هیچ کس دیگری نتواند از آن استفاده کند. در قراردادهای هوشمند، اگر یک کاربر مخرب تمام منابع موجود را مصرف کرده و از عملکرد صحیح قرارداد جلوگیری کند، ممکن است این اتفاق بیفتد.
نحوه جلوگیری از این حمله:
– مدیریت محدودیت هزینه گس: قرارداد خود را برای استفاده از گس بهینه کنید.
– توابع بازگشتی: اجرای حداقل عملکردهای بازگشتی که گس بسیار کمی مصرف میکنند.
– مکانیزمهای ایمن: مطمئن شوید که قرارداد شما میتواند در صورت بروز خطا به حالت ایمن بازگردد.
۵. فرانت رانینگ (Front-Running)
تصور کنید میخواهید یک محصول با نسخه محدود را آنلاین بخرید، اما شخصی که اینترنت سریعتری دارد، لحظهای قبل از اینکه روی «خرید» کلیک کنید، آن را خریداری میکند. این مورد شبیه به فرانت رانینگ در قراردادهای هوشمند است. مهاجم یک تراکنش معلق را میبیند و تراکنش خود را با کارمزدهای بالاتر ارسال میکند تا ابتدا آن را پردازش کند، بنابراین مزیت ناعادلانهای به دست میآورد.
نحوه جلوگیری از این حمله:
– Commit-Reveal Scheme: یک فرآیند دو مرحلهای را پیاده سازی کنید که در آن کاربران ابتدا به یک تراکنش متعهد میشوند و بعداً آن را آشکار میکنند.
– تأخیرهای تصادفی: تأخیرهای تصادفی یا قفلهای زمانی را معرفی کرده تا پیشروی را دشوارتر کنید.
– پروتکلهای سفارش عادلانه: از پروتکلهایی استفاده کنید که از سفارش مجدد تراکنشها بر اساس کارمزد جلوگیری میکند.
۶. مسائل مربوط به کنترل دسترسی (Access Control Issues)
مسائل مربوط به کنترل دسترسی مانند این است که کلیدهای خانه خود را زیر حصیر در بگذارید. اگر کسی بتواند به عملکردهای حیاتی قرارداد هوشمند شما دسترسی داشته باشد، یک خطر امنیتی به حساب میآید. کنترلهای دسترسی مناسب برای جلوگیری از دستکاری غیرمجاز بسیار مهم است.
نحوه جلوگیری از این حمله:
– از Modifiers استفاده کنید: Modifiers یا همان اصلاح کنندههای کنترل دسترسی را برای محدود کردن افرادی که میتوانند توابع خاصی را فراخوانی کنند، پیادهسازی کنید.
– کنترل دسترسی مبتنی بر نقش: از مکانیزمهایی برای اختصاص مجوزهای مختلف استفاده کنید. به عنوان مثال فقط صاحب قرارداد امکان فراخوانی بعضی از موارد را داشته باشد.
– تست کامل: آزمایشات و آدیت یا همان ممیزیهای امنیتی کامل را برای اطمینان از اجرای صحیح کنترلهای دسترسی انجام دهید.
۷. وابستگی مهر زمانی (Timestamp Dependence)
برخی از قراردادهای هوشمند برای عملیات خاص به مهر زمانی یک بلوک متکی هستند. با این حال، از آنجایی که ولیدیتورها بر روی این مهرهای زمانی کنترل دارند، میتوان آنها را در محدوده خاصی دستکاری کرد. این مورد مانند این است که ساعت خود را چند دقیقه سریع تنظیم کنید تا زودتر به قرار ملاقات برسید، اما در این حالت میتواند منجر به آسیبپذیری شود.
نحوه جلوگیری از این حمله:
– اجتناب از وابستگی بحرانی: از استفاده مهرهای زمانی بلوک برای عملیات حیاتی خودداری کنید.
– از شمارههای بلوک استفاده کنید: در صورت امکان، از شمارههای بلوک به جای مهر زمانی استفاده کنید.
– ترکیب منابع: اگر مهر زمانی لازم است، آنها را با سایر منابع تصادفی ترکیب کنید تا خطرات دستکاری کاهش یابد.
۸. حالت رندوم ناامن (Insecure Randomness)
تولید اعداد تصادفی در بلاک چین دشوار است زیرا همه چیز عمومی و قطعی است. حالت تصادفی ناامن میتواند قابل پیشبینی و سوءاستفاده باشد.
نحوه جلوگیری از این حمله:
– اوراکلهای خارج از زنجیره: از خدمات خارج از زنجیره یا همان آفچین برای تولید اعداد تصادفی امن استفاده کنید.
– طرحهای Commit-Reveal: با متعهد کردن کاربران به یک مقدار قبل از افشای آن، امنیت را افزایش دهید.
– چندین منبع تصادفی را برای بهبود امنیت ترکیب کنید.
۹. حمله به آدرس کوتاه (Short Address Attack)
حملات آدرس کوتاه زمانی اتفاق میافتد که یک آدرس در قرارداد به درستی به طول کامل آن اضافه نشده باشد. این مورد مانند اشتباه شمارش ارقام یک شماره تلفن است و در نهایت با شخص اشتباهی تماس میگیرید. در قراردادهای هوشمند، این مورد میتواند منجر به تفسیر نادرست دادههای تراکنش شود.
نحوه جلوگیری از این حمله:
– از سالیدیتی ۰.۵.۰ یا بالاتر استفاده کنید: نسخههای بالاتر سالیدیتی به طور خودکار آدرسها را به طول صحیح اضافه میکنند.
– اعتبارسنجی ورودی: طول و قالب تمام دادههای ورودی را اعتبارسنجی کرده تا از صحت آن اطمینان حاصل کنید.
در ادامه نیز میتوانید بیشتر این حملات را در قالب جدول مشاهده نمایید. البته که اگر بخواهیم تمام حملات را بیاوریم لیست بسیار بزرگی خواهد شد.
توضیح | نام |
زمانی رخ میدهد که یک تابع قبل از بهروزرسانی وضعیت، یک تماس خارجی برقرار کند. یک قرارداد مخرب میتواند دوباره وارد عملکرد شود و وجوه را سرقت کند. | ورود مجدد |
محاسباتی که از حد مجاز فراتر میروند می توانند منجر به نتایج غیرمنتظره شوند. | اورفلو و آندرفلو |
نقص در منطق کد که باعث رفتار ناخواسته میشود. | لاجیک ارور |
قراردادهای هوشمند برای اطلاعات به دادههای خارجی (اوراکل) متکی هستند. اگر اوراکل به خطر بیفتد، قرارداد میتواند گمراه شود. | اوراکل های غیر قابل اعتماد |
یک عامل مخرب میتواند قرارداد را با تراکنشها اسپم کند و از تعامل کاربران قانونی با آن جلوگیری کند. | حملات انکار سرویس (DoS) |
سایر آسیبپذیریهای رایج در قراردادهای هوشمند
در این بین یکی از مشکلات رایج، خطاهای کد موجود است، که اشکال یا اشتباهاتی در کد قرارداد هستند که میتوانند توسط مهاجمان مورد سوء استفاده قرار گیرند. این خطاها اغلب از پیچیدگی زبانهای قرارداد هوشمند مانند سالیدیتی ناشی میشوند. برای جلوگیری از این آسیبپذیریها، بسیار مهم است که کد را قبل از استقرار در بلاک چین به طور کامل آزمایش و ممیزی کنید.
در کنار آن فراموش کردن عملکرد خود تخریبی یک مسئله کمتر آشکار اما مهم است. تابع selfdestruct برای حذف یک قرارداد هوشمند از بلاک چین، آزاد کردن فضا و بازگرداندن احتمالی وجوه باقیمانده به یک آدرس مشخص استفاده میشود. اگر این تابع گنجانده نشود یا به درستی اجرا نشود، میتواند قرارداد را برای همیشه روی بلاک چین باقی بگذارد و باعث عواقب ناخواسته شود. برای جلوگیری از این امر، توسعهدهندگان باید چرخه عمر قراردادهای خود را به دقت در نظر گرفته و در صورت نیاز، مکانیزم امنی برای فسخ نهایی آنها در نظر بگیرند.
سوء استفاده از عملکرد delegatecall خطر جدی دیگری ایجاد میکند. Delegatecall به یک قرارداد اجازه میدهد تا کد را از قرارداد دیگری اجرا کند و در عین حال متن قرارداد اصلی را حفظ کند. اگر به درستی استفاده نشود، میتواند منجر به رفتارهای غیرمنتظره و آسیبپذیریهایی شود. برای جلوگیری از این امر، توسعهدهندگان باید از delegatecall با احتیاط استفاده کرده و اطمینان حاصل کنند که هر کد خارجی که فراخوانی میشود بهطور کامل بررسی و قابل اعتماد است.
نتیجهگیری: درک قراردادهای هوشمند و آسیبپذیریها
قراردادهای هوشمند دارای پتانسیل باورنکردنی برای خودکارسازی و ایمنسازی تراکنشهای دیجیتال هستند، اما باید به دقت طراحی و اجرا شوند تا از آسیب پذیریها جلوگیری شود. در ادامه چند نکته کلی وجود دارد که باید در نظر داشته باشید:
- ممیزیهای منظم: قراردادهای هوشمند خود را به طور مرتب توسط متخصصان امنیتی بازرسی کنید.
- از کتابخانهها استفاده کنید: برای عملکردهای رایج به کتابخانههای تست شده مانند OpenZeppelin تکیه کنید.
- به روز بمانید: با آخرین پیشرفتها در امنیت قراردادهای هوشمند همراه باشید و قراردادهای خود را بر این اساس به روز کنید.
- به طور کامل تست انجام دهید: آزمایشهای گستردهای را برای شناسایی و رفع آسیبپذیریها قبل از استقرار قرارداد خود روی بلاک چین انجام دهید.
با درک این آسیب پذیریهای رایج و نحوه جلوگیری از آنها، میتوانید مطمئن شوید که قراردادهای هوشمند شما ایمن و قابل اعتماد هستند. این مورد نه تنها از داراییهای دیجیتال شما محافظت میکند، بلکه باعث ایجاد اعتماد با کاربران و شرکای شما میشود که با قراردادهای هوشمند شما تعامل دارند. همانطور که این فناوری به تکامل خود ادامه میدهد، آگاه ماندن و فعال بودن در مورد امنیت، کلیدی برای استفاده از پتانسیل کامل قراردادهای هوشمند خواهد بود.
سوالات متداول
۱. قرارداد هوشمند چیست و چگونه کار میکند؟
قرارداد هوشمند یک قرارداد خوداجرا است که در آن شرایط قرارداد مستقیماً در کد کامپیوتری نوشته میشود. در صورت برآورده شدن شرایط از پیش تعریف شده، بدون نیاز به واسطه، به طور خودکار شرایط را اجرا میکند.
۲. آسیب پذیریهای رایج در قراردادهای هوشمند چیست؟
آسیبپذیریهای رایج شامل خطاهای کد، ناسازگاری با بهروزرسانیهای بلاک چین، استفاده نادرست یا عدم توابع خود تخریبی، و… است. این مسائل میتواند منجر به خطرات امنیتی و سوء استفادهها شود.
۳. توسعه دهندگان چگونه میتوانند از آسیبپذیری قرارداد هوشمند جلوگیری کنند؟
توسعهدهندگان میتوانند با آزمایش و ممیزی کامل کدشان، استفاده از کتابخانههای تثبیتشده، اطلاعرسانی در مورد بهروزرسانیهای بلاک چین، از جمله توابع ضروری مانند selfdestruct و… از آسیبپذیریها جلوگیری کنند.
۴. اگر آسیب پذیری در قرارداد هوشمند مستقر (دپلوی: به معنای این که این قرارداد بر روی بلاک چین اجرا شده) یافت شد چه باید کرد؟
اگر آسیبپذیری یافت شود، قرارداد باید در صورت امکان متوقف شود تا از سوءاستفادههای بیشتر جلوگیری شود. سپس توسعهدهندگان باید قرارداد را با یک اصلاح بهروزرسانی کنند و در صورت لزوم، به نسخه جدید قرارداد مهاجرت کنند و کاربران را از تغییر و هرگونه اقدامی که باید انجام دهند مطلع کنند.
دیدگاهها