استمرار المقال "فحص عقود Ethereum الحية بحثًا عن خطأ إرسال لم يتم التحقق منه". الجزء 1 " .
قبل عام تقريبًا (بينما كانت Ethereum في إصدارها "الحدودي") ، عانى عقد يانصيب EtherPot الشهير [9] أيضًا من نفس الخطأ. كما أظهر إصدار سابق من BTCRelay هذا الخطأ [7] . على الرغم من اكتشاف خطر في مراجعة أمنية سابقة ، تم تطبيق تصحيح غير صحيح لأول مرة [8] .
الكشف عن خطأ إرسال لم يتم التحقق منه على blockhain الحية
ما مدى شيوع هذه الأخطاء؟ هل يستمعون للتحذيرات؟ هل يتم تطبيق أفضل الممارسات؟ نجيب على هذه الأسئلة تجريبيا من خلال تحليل البيانات من سلسلة كتلة Ethereum ، وكذلك مستودع رمز Solidity الموجود على etherscrape.com. للقيام بذلك ، نقوم بتطوير أداة بسيطة لتحليل البرنامج تتحقق من عقد سلسلة السلسلة وتستخدم الاستدلال للتحقق مما إذا كانت إحدى طرق الحماية الأكثر فعالية مستخدمة. تظهر القائمة 2 تقنية الأمان الأولى ، على النحو الموصى به في وثائق Ethereum ، والتي يجب أن تتحقق من القيمة المرتجعة للإرسال وترمي استثناء. للكشف عن استخدام هذه الطريقة ، نستخدم تقريبًا تقريبيًا: ننظر فقط إذا تم تجاهل القيمة المرجعة للإرسال أم لا.
توضح القائمة 4 تقنية الأمان الثانية الموصى بها في دليل UMD ، والتي تتحقق مباشرة مما إذا كانت حزمة المكالمات ممتلئة عن طريق إرسال رسالة اختبار. لاكتشاف هذه التقنية ، نستخدم مرة أخرى تقريبًا تقريبًا: نتحقق فقط لمعرفة ما إذا كان يتم إرسال رسالة بالإضافة إلى أمر الإرسال .
في حالة عدم وجود أي من هذه المؤشرات الكشفية ، نستنتج أنه لا يتم اتباع أي من أفضل الممارسات العملية. نقوم بتطبيق هذه الاستدلال باستخدام مطابقة الأنماط البسيطة مع رمز EVM المترجمة. يمكن العثور على مزيد من التفاصيل حول كيفية القيام بذلك في الملحق [12] .
كم عدد العقود الضعيفة؟
لنبدأ بالتحقق من الارشادي في مستودع Etherscrape من كود مصدر Solidity. اعتبارًا من 20 مارس 2016 ، احتوى تتابع Etherscrape على 361 برنامجًا للعقود الصلبة ، يحتوي 56 منها على بيان إرسال. من بين برامج العقود هذه ، نفترض أن معظم (36 على الأقل من 56) لا يستخدمون أيًا من طرق البرمجة الدفاعية.
حتى إذا كان العقد لا يستخدم أيًا من تقنيات الحماية ، فقد يكون أو لا يكون له ثغرة حقيقية. لقد تحققنا يدويًا من عقود Solidity لتأكيد الثغرة الأمنية. لأغراضنا ، نعتبر العقد ضعيفًا إذا كان يمكن تغيير حالته حتى إذا لم يعمل أمر الإرسال (لذلك سنلقي نظرة على الرمز الضعيفة في القائمة 5). أكدنا أن الغالبية العظمى من نقاط الضعف موجودة ، 32 من 36 من هذه العقود.
وبالمثل ، لا يضمن استدلالنا التطبيق الصحيح للبرمجة الدفاعية. خذ ، على سبيل المثال ، WeiFund ، DApp اللامركزي مفتوح المصدر للتمويل الجماعي. يحتوي هذا العقد على وظيفتين: استرداد () ودفع () ، مما يخدع استدلالنا. ما يلي مقتطف من المبلغ المسترد .
function refund(uint _campaignID, uint contributionID) public { ... receiver.send(donation.amountContributed); donation.refunded = true; ... if(c.config != address(0)) WeiFundConfig(c.config).refund(_campaignID, donation.contributor, donation.amountContributed); }
في هذا الرمز ، يتم إرسال رسالة إلى WeiFundConfig (c.config) لاستدعاء طريقة رد الأموال ، ولكن فقط في ظل ظروف معينة. إذا كانت c.config قيمة خالية ، فإن العقد يكون عرضة لهجوم مكدس. عند التحقق * ، لم يطبق أي من برامج Solidity التي اجتازت اختبارنا التوجيهي أفضل ممارسات اختبار Callstack الموصى بها مباشرة. *
ثم ننتقل إلى العقود التي تمت صياغتها في سلسلة Ethereum الحية. نظرنا إلى الصورة بتاريخ 20 مارس 2016 (الطابع الزمني: 1184243). تحتوي هذه اللقطة على ما مجموعه 13645 سلسلة كتلة ، والتي تم إنشاؤها على ما يبدو من قبل المترجم Solidity ، منها 1618 (11.8 ٪) فقط تضمنت أمر الإرسال .
ولا يبدو أن الغالبية العظمى من هؤلاء تستخدم أيًا من تقنيات البرمجة الدفاعية.
ماذا عن مشكلة العودية العودية في TheDAO؟ العقد الذكي الأكثر إثارة هذه الأيام ، TheDAO [11] ، يعاني من خطأ منفصل تمامًا ، وهو أنه ليس "آمنًا لإعادة الاستخدام" [13] . هذا هو نوع آخر (متصل ، ولكن متميز) من البرمجة غير الآمنة ، والذي كان متوقعًا أيضًا في الفحوصات الأمنية السابقة [6] ، ولكن ، كما كان من قبل ، من المحتمل أن العديد من العقود غير آمنة اليوم. كان العمل المستقبلي هو صنع أداة يمكنها أيضًا اكتشاف مثل هذا الخطأ.
أين ذهب كل شيء خاطئ؟
لا نتوقع أن تكون برمجة العقود الذكية بسيطة للغاية ، على الأقل في الوقت الحالي. ومع ذلك ، من المدهش أن هذا الشكل الخاص من الخطأ منتشر على نطاق واسع ، على الرغم من أنه تم وصفه منذ فترة طويلة أثناء تطوير النظام البيئي Ethereum.
قدم تقرير 2015 [6] هذه التوصية لمطوري Ethereum: "
حاليا ، الأمثلة البرمجية المقدمة في الوثائق غير كافية لنشر أفضل الممارسات لكتابة عقود آمنة وحل مشكلة آلية الغاز. غالبًا ما تخطي الدروس التمهيدية لـ C ++
التحقق من الأخطاء لقابلية القراءة ، مما أدى إلى العديد من الأخطاء الأمنية. يجب أن تعلم أمثلة Ethereum أفضل العادات. توصية: قدم المزيد من الأمثلة على البرمجة الدقيقة للعقود الأمنية ".
نحن نعرف إجابة رسمية واحدة فقط على هذا السؤال ، وهي إضافة تحذير إلى وثائق Solidity الرسمية المذكورة سابقًا [3] ، المكررة أدناه: "هناك بعض المخاطر عند استخدام الإرسال : فشل الإرسال إذا كان عمق مكدس المكالمة 1024 (يمكن أن يتصل المتصل بذلك دومًا) ، ويفشل أيضًا في حالة نفاد غاز المستلم ، لذا لضمان البث الآمن ، تحقق دائمًا من القيمة المرجعة للإرسال أو حتى أفضل: استخدم النمط الذي يسحب فيه المتلقي الأموال ".
نعتقد أن هذه الملاحظة ليست كافية لتوثيق المشكلة. لا يقدم سوى التخفيف غير المكتمل ويصف نسخة واحدة فقط من الخطر ، ومن المحتمل أن يضلل القارئ بشأن درجته.
بالإضافة إلى ذلك ، يبدو أن التحذير غالبًا ما يتم تجاهله. لذلك ، نعتقد أن التدابير الوقائية الإضافية ضرورية.
كيف يمكن أن يساعد Etherscrape؟
نعتقد أن استخدام أدوات التحليل الثابت ، حتى الأدوات الأولية ، مثل تلك الموضحة في هذا المنشور ، يمكن أن تساعد في تحسين جودة العقود الذكية. في Etherscrape ، ندمج أدوات التحليل مثل هذه في خدمة الويب العامة الخاصة بنا ، ونضيف رابطًا إلى صفحة الأداة عندما تكون جاهزة. سيؤدي ذلك إلى تسهيل عرض رمز العقد الذكي من خلال تمييز الأماكن التي قد تحدث فيها أخطاء. نفترض أن مستخدمي مثل هذا العقد الذكي (على سبيل المثال ، المستثمرين المحتملين في TheDAO أو عروضه) يمكنهم بسهولة استخدام أدوات مثل التحقق من السلامة قبل إيداع أموالهم. حتى المستثمرون غير التقنيين يمكن أن يحاسبوا المطورين على تفسير كيفية تفاعلهم مع المشكلات المذكورة في الكود.
يساعد Etherscrape أيضًا من خلال تحليل سلسلة الكتلة العامة والتحكم في انتشار هذا الخطأ ، والذي يمكن أن يساعد في تحديد ، على سبيل المثال ، مقدار المال الذي يجب تخصيصه للبحث وتطوير أدوات التحليل الثابتة. بالإضافة إلى ذلك ، يمكن للمجمعين مثل solc دمج هذه التحليلات ، مما يوفر تحذيرًا للمبرمج عندما يبدو الخطأ محتملًا.
القراءة الموصى بها