تحليل ثغرات مترجم Solidity واستراتيجيات الأمان للمطورين

تحليل ثغرات مترجم Solidity واستراتيجيات الاستجابة

المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة. إنه برنامج كمبيوتر، والوظيفة الرئيسية له هي تحويل كود مصدر لغة البرمجة عالية المستوى الذي يسهل على البشر فهمه وكتابته إلى تعليمات قابلة للتنفيذ من قبل وحدة المعالجة المركزية أو آلة افتراضية لبايت كود.

غالبًا ما يركز معظم المطورين وخبراء الأمان على أمان رمز تطبيقات البرامج، لكن قد يتجاهلون مشكلات أمان المترجم نفسه. في الواقع، فإن المترجم كبرنامج حاسوبي، يحتوي أيضًا على ثغرات أمنية، وهذه الثغرات قد تشكل مخاطر أمنية خطيرة في حالات معينة. على سبيل المثال، أثناء عملية تجميع وتحليل وتنفيذ رمز JavaScript من جانب العميل، قد تؤدي ثغرات في محرك تحليل JavaScript إلى استغلال المهاجمين الثغرات عند زيارة المستخدمين لمواقع ويب ضارة، مما يسمح لهم بتنفيذ تعليمات برمجية عن بُعد، والسيطرة في النهاية على متصفح الضحية أو حتى نظام التشغيل.

لا يُستثنى مترجم Solidity من ذلك، وفقًا لتحذيرات أمان فريق تطوير Solidity، توجد ثغرات أمنية في عدة إصدارات مختلفة من مترجم Solidity.

ثغرة مترجم Solidity

تتمثل وظيفة مترجم Solidity في تحويل شفرة عقود الذكاء التي كتبها المطورون إلى كود تعليمات EVM( الخاص بـ Ethereum Virtual Machine)، حيث يتم تحميل هذه التعليمات EVM من خلال حزم المعاملات إلى Ethereum، وأخيراً يتم تفسيرها وتنفيذها بواسطة EVM.

يجب التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. تشير ثغرات EVM إلى المشكلات الأمنية الناتجة عن تنفيذ التعليمات في الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي رمز إلى Ethereum، سيتم تشغيل هذه الرموز في النهاية في كل برنامج عميل P2P على Ethereum، وإذا كانت هناك ثغرات أمنية في EVM، فسوف تؤثر على شبكة Ethereum بالكامل، مما قد يؤدي إلى رفض الخدمة في الشبكة بالكامل (DoS) أو حتى السيطرة الكاملة عليها من قبل المهاجمين. ومع ذلك، نظرًا لتصميم EVM البسيط نسبيًا، وأن الشيفرة الأساسية لا يتم تحديثها بشكل متكرر، فإن احتمال حدوث مثل هذه المشكلات يكون منخفضًا.

تشير ثغرات مترجم Solidity إلى المشكلات التي تحدث عند تحويل Solidity إلى كود EVM. على عكس سيناريوهات مثل المتصفحات التي تقوم بتجميع وتشغيل JavaScript على جهاز الكمبيوتر الخاص بالمستخدم، يتم إجراء عملية تجميع Solidity فقط على جهاز الكمبيوتر لمطور العقد الذكية، ولن تعمل على شبكة Ethereum. لذلك، فإن ثغرات مترجم Solidity لن تؤثر على شبكة Ethereum نفسها.

تتمثل إحدى الأضرار الرئيسية لثغرات مترجم Solidity في أنها قد تؤدي إلى اختلاف الكود الناتج عن EVM عن توقعات مطوري العقود الذكية. نظرًا لأن العقود الذكية على إيثيريوم تتعلق عادةً بأصول العملات المشفرة للمستخدمين، فإن أي خطأ في العقد الذكي ناتج عن المترجم قد يتسبب في خسارة أصول المستخدمين، مما يؤدي إلى عواقب وخيمة.

قد يركز المطورون ومراجعو العقود على مشكلات تنفيذ منطق كود العقد ، بالإضافة إلى مشكلات الأمان على مستوى Solidity مثل إعادة الإدخال وتجاوز السعة العددية. أما بالنسبة لثغرات مترجم Solidity ، فمن الصعب اكتشافها فقط من خلال مراجعة منطق كود العقد. يحتاج الأمر إلى تحليل مشترك بين إصدار مترجم معين ونمط كود محدد لتحديد ما إذا كانت العقود الذكية متأثرة بثغرات المترجم.

تحليل ثغرات مترجم Solidity وإجراءات التعامل معها

مثال على ثغرة في مترجم Solidity

تظهر الفقرات التالية من خلال عدة حالات حقيقية لثغرات مترجم Solidity، الأشكال المحددة، والأسباب، والضرر.

SOL-2016-9 HighOrderByteCleanStorage

توجد هذه الثغرة في الإصدارات المبكرة من مترجم Solidity (>=0.1.6 <0.4.4).

النظر في الكود التالي:

الصلابة عقد C { uint32 أ = 0x1234; uint32 ب = 0 ؛ وظيفة f() عامة { a += 1; } ترجع الدالة run() العرض العام (uint32) { عودة b; } }

لم يتم تعديل المتغير b في التخزين، لذا يجب أن تعيد الدالة run() القيمة الافتراضية 0. ولكن في الكود الذي تم إنتاجه بواسطة نسخة المترجم المعرضة للثغرات، ستعيد الدالة run() القيمة 1.

إذا لم يكن لديك فهم لثغرة المترجم، سيكون من الصعب على المطورين العاديين اكتشاف الأخطاء الموجودة في الكود أعلاه من خلال مراجعة بسيطة للكود. هذه مجرد مثال بسيط، لن يؤدي إلى عواقب خطيرة بشكل خاص. ولكن إذا تم استخدام المتغير b للتحقق من الأذونات، أو محاسبة الأصول، فإن هذا التباين عن المتوقع قد يؤدي إلى مشاكل خطيرة للغاية.

سبب هذه الظاهرة الغريبة هو أن EVM يستخدم آلة افتراضية قائمة على المكدس، وكل عنصر في المكدس بحجم 32 بايت ( أي بحجم متغير uint256 ). من ناحية أخرى، كل فتحة في التخزين الأساسي storage أيضًا بحجم 32 بايت. تدعم لغة Solidity أنواع البيانات المختلفة التي تقل عن 32 بايت مثل uint32، وعندما يتعامل المجمع مع هذه المتغيرات، يحتاج إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا (clean up) لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما تحدث زيادة تؤدي إلى تجاوز عدد صحيح، لم يقم المجمع بتنظيف الأجزاء العليا للنتيجة بشكل صحيح، مما أدى إلى كتابة بت واحد في الجزء العلوي الناتج إلى التخزين، مما أدى في النهاية إلى覆盖 المتغير a للمتغير b، مما جعل قيمة المتغير b تتغير إلى 1.

SOL-2022-4 آثار جانبية للذاكرة في التجميع الداخلي

اعتبر الكود التالي:

صلابة العقد C { وظيفة f() العوائد العامة النقية (uint) { تجميع { mstore(0 ، 0x42) } uint x; تجميع { x := mload(0) } عودة x; } }

توجد هذه الثغرة في المترجم من النسخ >=0.8.13 و <0.8.15. لا يقوم مترجم Solidity ببساطة بترجمة لغة Solidity إلى رموز EVM، بل يقوم أيضًا بتحليل تدفق التحكم والبيانات بعمق، وتنفيذ عمليات تحسين متنوعة أثناء عملية الترجمة لتقليل حجم الرموز الناتجة وتحسين استهلاك الغاز أثناء التنفيذ. هذه الأنواع من عمليات التحسين شائعة في مترجمات اللغات عالية المستوى، ولكن نظرًا للتعقيد الكبير في الحالات التي يجب أخذها بعين الاعتبار، فمن السهل أيضًا حدوث أخطاء أو ثغرات أمنية.

تأتي ثغرة الشيفرة المذكورة من هذا النوع من عمليات التحسين. افترض أن هناك كودًا في وظيفة معينة يقوم بتعديل بيانات في موضع الذاكرة 0، ولكن لا توجد أي مكان آخر يستخدم هذه البيانات بعد ذلك، لذا يمكن في الواقع إزالة كود تعديل الذاكرة 0 مباشرة، مما يوفر الغاز، دون التأثير على منطق البرنامج اللاحق.

هذه الاستراتيجية التحسينية ليست بها مشكلة، ولكن في تنفيذ كود مترجم Solidity، يتم تطبيق هذا النوع من التحسين فقط على كتلة assembly واحدة. في كود PoC المذكور، يوجد الكتابة والوصول إلى الذاكرة 0 في كتلتي assembly مختلفتين، بينما يقوم المترجم بتحليل وتحسين كتلة assembly بشكل منفصل فقط. نظرًا لعدم وجود أي عمليات قراءة بعد الكتابة إلى الذاكرة 0 في الكتلة الأولى، يتم اعتبار أمر الكتابة هذا زائدًا، وسيتم إزالته، مما يتسبب في حدوث خطأ. في الإصدار المعرض للخطر، ستعيد الدالة f() القيمة 0، بينما القيمة الصحيحة التي يجب أن تعيدها الشفرة المذكورة هي 0x42.

SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

اعتبر الشيفرة التالية:

صلابة العقد C { الدالة f(string[1] بيانات المكالمات a) إرجاع خارجي (string memory) { إرجاع abi.decode(abi.encode(a), (string)); } }

تؤثر الثغرة على المترجمات التي تتراوح إصداراتها بين 0.5.8 و 0.8.16. في الظروف العادية، يجب أن تكون قيمة المتغير a التي يتم إرجاعها من الكود أعلاه هي "aaaa". ولكن في إصدارات الثغرة، سيتم إرجاع سلسلة فارغة "".

سبب هذه الثغرة هو أن Solidity قامت بعملية abi.encode لمصفوفات نوع calldata، وأخطأت في تنظيف بعض البيانات، مما أدى إلى تعديل بيانات أخرى مجاورة، مما تسبب في عدم توافق البيانات بعد عملية الترميز والفك.

من الجدير بالذكر أن Solidity يقوم بشكل ضمني بترميز المعاملات باستخدام abi.encode عند إجراء مكالمة خارجية وإصدار حدث، وبالتالي فإن احتمال ظهور ثغرة الشيفرة المذكورة أعلاه سيكون أعلى مما يبدو للوهلة الأولى.

تحليل الثغرات في مترجم Solidity والتدابير المتخذة

نصائح الأمان

قدمت فريق أمان بلوكتشين Cobo بعد تحليل نموذج تهديد الثغرات في مترجم Solidity واستعراض الثغرات التاريخية، الاقتراحات التالية للمطورين وموظفي الأمن.

للمطورين:

  • استخدم إصدارًا أحدث من مترجم Solidity. على الرغم من أن الإصدارات الجديدة قد تقدم مشكلات أمان جديدة، إلا أن المشكلات الأمنية المعروفة عادة ما تكون أقل من الإصدارات القديمة.

  • تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم تؤدي إلى نتائج تنفيذ الشيفرة غير متوافقة مع التوقعات. هذه النوعية من المشاكل من الصعب اكتشافها من خلال مراجعة الشيفرة، ولكنها تظهر بسهولة في مرحلة الاختبار. لذلك، من خلال زيادة تغطية الشيفرة، يمكن تقليل هذه المشاكل إلى الحد الأدنى.

  • حاول تجنب استخدام التجميع الداخلي، والترميز وفك الترميز المعقد لـ ABI مع المصفوفات متعددة الأبعاد والهياكل المعقدة، وتجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى من أجل التفاخر عندما لا تكون هناك حاجة واضحة. وفقًا لفريق أمان Cobo الذي قام بمراجعة الثغرات التاريخية في Solidity، فإن معظم الثغرات مرتبطة بالتجميع الداخلي، وعمليات ترميز ABI وما إلى ذلك. من الأسهل أن تحدث الأخطاء في المترجم عند التعامل مع ميزات اللغة المعقدة. من ناحية أخرى، من السهل أيضًا على المطورين الوقوع في أخطاء عند استخدام الميزات الجديدة، مما يؤدي إلى مشكلات أمان.

إلى الأمن:

  • عند إجراء تدقيق أمني لرمز Solidity، لا تتجاهل المخاطر الأمنية التي قد يقدمها مترجم Solidity. البند المقابل في تصنيف نقاط ضعف العقود الذكية ( SWC) هو SWC-102: إصدار المترجم قديم.

  • خلال عملية تطوير SDL الداخلية، يتم حث فريق التطوير على ترقية إصدار مترجم Solidity، ويمكن النظر في إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.

  • ولكن لا داعي للذعر المفرط بشأن ثغرات المترجم، حيث يتم تنشيط معظم ثغرات المترجم فقط في أنماط معينة من الشيفرة، وليس من الضروري أن يكون هناك خطر أمني عند استخدام عقود تم تجميعها بواسطة إصدارات مترجم تحتوي على ثغرات، حيث يتعين تقييم التأثير الأمني الفعلي بناءً على حالة المشروع.

موارد عملية:

  • تنبيهات الأمان التي ينشرها فريق Solidity بشكل دوري:

  • قائمة الأخطاء التي يتم تحديثها بانتظام في مستودع Solidity الرسمي:

  • قائمة أخطاء المترجمات في الإصدارات المختلفة:

الكود تشير إلى الثغرات الأمنية الموجودة في إصدار المجمع الحالي.

ملخص

تبدأ هذه المقالة بمفهوم المترجم الأساسي، وتقدم ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تؤدي إليها في بيئة تطوير Ethereum الفعلية، وأخيرًا تقدم عددًا من النصائح الأمنية العملية للمطورين وموظفي الأمن.

تحليل ثغرات مترجم Solidity وإجراءات التعامل معها

ETH2.9%
شاهد النسخة الأصلية
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
  • أعجبني
  • 5
  • مشاركة
تعليق
0/400
staking_grampsvip
· منذ 16 س
تعدد الثغرات، من يجرؤ على التطوير بعد الآن؟
شاهد النسخة الأصليةرد0
JustHereForMemesvip
· 07-23 05:15
المترجم لديه مشاكل كبيرة أيضا، سأذهب الآن.
شاهد النسخة الأصليةرد0
BakedCatFanboyvip
· 07-22 21:56
العيوب تعتمد على الالتقاط أليس كذلك
شاهد النسخة الأصليةرد0
OldLeekNewSicklevip
· 07-22 21:56
الحمقى المتقدمون يبحثون عن الثغرات، والحمقى الأساسيون يركزون على دفتر الطلبات
شاهد النسخة الأصليةرد0
RektCoastervip
· 07-22 21:52
هل تحدث أخطاء في المترجم أيضًا؟ حقًا يجعلني أظهر وأتفجر في الشارع
شاهد النسخة الأصليةرد0
  • تثبيت