تحليل ثغرات مترجم Solidity واستراتيجيات التعامل معها
المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة. إنه برنامج حاسوبي، وظيفته تحويل الشيفرة المصدرية للغات البرمجة عالية المستوى التي يسهل على الإنسان فهمها وكتابتها إلى تعليمات قابلة للتنفيذ من قبل وحدة المعالجة المركزية أو آلة بايت كود.
عادةً ما يكون معظم المطورين وخبراء الأمان مهتمين بأمان كود تطبيقات البرامج، لكن قد يتجاهلون أمان المترجم نفسه. في الواقع، يمكن أن يحتوي المترجم، كبرنامج حاسوبي، على ثغرات أمنية، وقد تؤدي الثغرات الأمنية الناتجة عن المترجم في بعض الحالات إلى مخاطر أمان خطيرة. على سبيل المثال، خلال عملية تجميع وتحليل وتنفيذ كود Javascript في الواجهة الأمامية، قد يؤدي وجود ثغرة في محرك تحليل Javascript إلى استغلال المهاجمين الثغرة لتحقيق تنفيذ كود عن بُعد، مما يمكنهم في النهاية من السيطرة على متصفح الضحية أو حتى نظام التشغيل. أظهرت بعض الدراسات أن أخطاء مترجم Clang C++ يمكن أن تؤدي أيضًا إلى تنفيذ كود عن بُعد وما إلى ذلك من عواقب وخيمة.
لم يكن مترجم Solidity استثناءً، وفقًا لتنبيه الأمان من فريق تطوير Solidity، توجد ثغرات أمان في عدة إصدارات مختلفة من مترجم Solidity.
ثغرة مترجم سوليديتي
تتمثل وظيفة مترجم Solidity في تحويل كود العقد الذكي الذي كتبه المطورون إلى كود تعليمات آلة Ethereum (EVM)، ويتم تحميل هذه تعليمات EVM من خلال معاملات مدمجة إلى Ethereum، وأخيراً يتم解析ها وتنفيذها بواسطة EVM.
يجب التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. تشير ثغرات EVM إلى الثغرات الأمنية التي تحدث أثناء تنفيذ التعليمات في الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي كود إلى الإيثريوم، فإن هذا الكود سيتم تنفيذه في كل برنامج عميل P2P للإيثريوم، وإذا كانت هناك ثغرات أمنية في EVM، فإن ذلك سيؤثر على الشبكة بأكملها، مما قد يتسبب في رفض الخدمة (DoS) أو حتى يؤدي إلى سيطرة كاملة للمهاجمين على السلسلة. ومع ذلك، نظرًا لأن تصميم EVM بسيط نسبيًا، وأن الكود الأساسي لا يتم تحديثه بشكل متكرر، فإن احتمال ظهور المشكلات المذكورة أعلاه منخفض نسبيًا.
ثغرات مترجم Solidity تشير إلى وجود ثغرات أثناء تحويل المترجم لغة Solidity إلى كود EVM. على عكس السيناريوهات التي يتم فيها تجميع وتشغيل Javascript على أجهزة الكمبيوتر العميلة للمستخدمين، فإن عملية تجميع Solidity تتم فقط على أجهزة الكمبيوتر الخاصة بمطوري العقود الذكية، ولا يتم تشغيلها على شبكة Ethereum. لذلك، فإن ثغرات مترجم Solidity لن تؤثر مباشرة على شبكة Ethereum نفسها.
تتمثل إحدى الأضرار الرئيسية لثغرات مترجم سوليدتي في أنها قد تؤدي إلى عدم تطابق كود EVM الناتج مع توقعات مطوري العقود الذكية. نظرًا لأن العقود الذكية على إيثريوم تتعلق عادةً بأصول العملات المشفرة للمستخدمين، فإن أي خطأ ينتج عن المترجم في العقود الذكية يمكن أن يتسبب في خسارة أصول المستخدمين، مما يؤدي إلى عواقب وخيمة.
قد تركز المطورون ومراجعي العقود على مشكلات تنفيذ منطق كود العقد، بالإضافة إلى مشكلات الأمان على مستوى Solidity مثل إعادة الإدخال وتجاوز الأعداد الصحيحة. ومع ذلك، من الصعب جداً اكتشاف ثغرات مترجم Solidity فقط من خلال تدقيق منطق شفرة العقد المصدر. تحتاج إلى تحليل مشترك بين إصدار المترجم المحدد وأنماط الشفرة المحددة لتحديد ما إذا كانت العقود الذكية تتأثر بثغرات المترجم.
مثال على ثغرات مترجم Solidity
تظهر الأمثلة الحقيقية التالية لحالات ثغرات مترجم Solidity أشكال الثغرات في مترجم Solidity وأسبابها وأضرارها.
SOL-2016-9 تخزين نظيف للبايت عالي الطلب
توجد هذه الثغرة في إصدارات أقدم من مجمع Solidity (≥0.1.6 <0.4.4).
اعتبر الكود التالي:
صلابة
العقد C {
uint32 أ = 0x12345678;
uint16 ب = 0x1234 ؛
وظيفة f() عامة {
a = a + 1;
}
ترجع الدالة run() العرض العام (uint16) {
ارجع b;
}
}
لم يتم تعديل المتغير storage b على الإطلاق، لذلك يجب أن تعيد الدالة run() القيمة الافتراضية 0. لكن في الواقع، في الكود الناتج عن إصدار المترجم الذي يحتوي على ثغرة، ستعيد الدالة run() القيمة 1.
من الصعب على المطورين العاديين اكتشاف الأخطاء الموجودة في الشيفرة المذكورة أعلاه من خلال مراجعة الشيفرة البسيطة دون فهم ثغرات المترجم. الشيفرة المذكورة أعلاه هي مجرد مثال بسيط، وبالتالي لن تسبب ضرراً خطيراً بشكل خاص. ولكن إذا تم استخدام المتغير b للتحقق من الأذونات، أو محاسبة الأصول، فإن هذا الاختلاف عن المتوقع قد يؤدي إلى عواقب وخيمة جداً.
سبب ظهور الظواهر الشاذة المذكورة أعلاه هو أن EVM تستخدم آلة افتراضية قائمة على المكدس، حيث كل عنصر في المكدس بحجم 32 بايت ( أي بحجم متغير uint256 ). من ناحية أخرى، كل فتحة في التخزين الأساسي storage أيضًا بحجم 32 بايت. بينما تدعم لغة Solidity أنواع بيانات مختلفة مثل uint32 وأي نوع آخر أقل من 32 بايت، عند معالجة مثل هذه الأنواع من المتغيرات، يحتاج المترجم إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا (clean up) لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما يحدثoverflow في الجمع، لم يقم المترجم بتنظيف الأجزاء العليا من النتيجة بشكل صحيح، مما أدى إلى كتابة البت 1 في الأجزاء العليا في التخزين، مما أدى في النهاية إلى الكتابة فوق المتغير a وتعديل قيمة المتغير b إلى 1.
SOL-2022-4 آثار ذاكرة التجميعات المضمنة
توجد هذه الثغرة في المترجمين من الإصدارات >=0.8.13 <0.8.15. أثناء تحويل لغة سوليديتي إلى كود EVM، لا يقوم مترجم سوليديتي ببساطة بترجمة النص. بل إنه يقوم أيضًا بتحليل عميق لتدفق التحكم والبيانات، ويحقق مجموعة متنوعة من عمليات تحسين الترجمة لتقليل حجم الكود الناتج، وتحسين استهلاك الغاز أثناء عملية التنفيذ. تعتبر هذه الأنواع من عمليات التحسين شائعة في مترجمات العديد من اللغات عالية المستوى، ولكن نظرًا لتعقيد الحالات التي يجب أخذها في الاعتبار، فإنها عرضة لظهور أخطاء أو ثغرات أمنية.
اعتبر الشيفرة التالية:
السوليديتي
العقد C {
وظيفة f() العوائد العامة النقية (uint256) {
التجميع {
mstore(0 ، 0x42)
}
uint256 x;
التجميع {
x := mload(0)
}
عودة x;
}
}
تأتي ثغرة الكود المذكور من عمليات تحسين التجميع. في بعض الحالات، إذا كان هناك كود يقوم بتعديل البيانات في موضع الذاكرة 0 داخل الدالة، ولكن لم يتم استخدام هذه البيانات في أي مكان لاحق، يمكن فعليًا إزالة كود تعديل الذاكرة 0 مباشرة، مما يوفر الغاز، دون التأثير على منطق البرنامج اللاحق.
استراتيجية التحسين هذه ليست بها مشكلة، لكن في تنفيذ كود مترجم Solidity المحدد، يتم تطبيق مثل هذه التحسينات فقط داخل كتلة assembly واحدة. في الشيفرة المثال المذكورة أعلاه، تتم الكتابة والوصول إلى الذاكرة 0 في كتلتين assembly مختلفتين، بينما يقوم المترجم بتحليل وتحسين كتلة assembly بشكل منفصل فقط. نظرًا لأنه لا توجد أي عمليات قراءة بعد كتابة الذاكرة 0 في الكتلة assembly الأولى، يتم تحديد أن تعليمات الكتابة هذه زائدة، وسيتم إزالة هذه التعليمات، مما يؤدي إلى حدوث خطأ. في النسخة التي تحتوي على الثغرة، ستعيد الدالة f( القيمة 0، بينما يجب أن تعيد الشيفرة المذكورة أعلاه القيمة الصحيحة 0x42.
تؤثر هذه الثغرة على المترجمات من الإصدار >= 0.5.8 إلى < 0.8.16. اعتبر الكود التالي:
صلابة
العقد C {
الدالة f###bytes بيانات الاتصال data( عوائد نقية خارجية )bytes memory( {
ذاكرة bytes4) أ = [bytes4[1]data(] ؛
إرجاع abi.encode019283746574839201a);
}
}
في الظروف العادية، يجب أن تُرجع الشيفرة أعلاه المتغير a كـ "aaaa". ولكن في النسخة التي تحتوي على ثغرات، ستُرجع سلسلة فارغة "".
سبب هذا الثغرة هو أن Solidity عند إجراء عملية abi.encode على مصفوفات من نوع calldata، قامت بشكل خاطئ بتنظيف بعض البيانات، مما أدى إلى تعديل بيانات أخرى مجاورة، مما تسبب في عدم توافق البيانات بعد التشفير وفك التشفير.
من الجدير بالذكر أن Solidity عند إجراء استدعاء خارجي و emit event، تقوم بشكل ضمني بترميز المعلمات باستخدام abi.encode، لذا فإن احتمال ظهور الثغرة المذكورة أعلاه سيكون أعلى مما يتصور.
تم تعديل هذه الثغرة لتصبح سؤالًا مشهورًا في مسابقة الأمان 0ctf 2022، حيث عرضت تأثير ثغرات المجمع على العقود الذكية في سيناريوهات التطوير الحقيقية.
نصائح الأمان
بالنسبة لتهديدات ثغرات مترجم Solidity والتعامل معها، يمكن تقديم الاقتراحات التالية:
إلى المطورين:
استخدم إصدارًا أحدث من مترجم Solidity. على الرغم من أن الإصدارات الجديدة قد تقدم مشكلات أمان جديدة، إلا أن المشكلات المعروفة عادةً ما تكون أقل من الإصدارات القديمة.
تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم ستؤدي إلى نتائج تنفيذ الكود غير متوافقة مع التوقعات. من الصعب اكتشاف هذه الأنواع من المشاكل من خلال مراجعة الكود، لكنها تظهر بسهولة في مرحلة الاختبار. لذلك، فإن زيادة تغطية الكود يمكن أن تتجنب هذه المشاكل إلى أقصى حد.
حاول تجنب استخدام التجميع الداخلي، والترميز وفك الترميز المعقد لهيكلية البيانات متعددة الأبعاد، وما إلى ذلك من العمليات المعقدة. تجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى عندما لا تكون هناك حاجة واضحة. ترتبط معظم الثغرات بالعمليات مثل التجميع الداخلي، ومشفرات ABI. من الأرجح أن يظهر أخطاء في المترجم عند التعامل مع ميزات اللغة المعقدة. من ناحية أخرى، قد يقع المطورون في أخطاء عند استخدام الميزات الجديدة، مما يؤدي إلى مشاكل أمان.
إلى موظفي الأمن:
عند إجراء تدقيق أمان لرمز Solidity، لا تغفل عن المخاطر الأمنية التي قد يقدمها مترجم Solidity. العنصر المقابل في تصنيف نقاط الضعف للعقود الذكية ( SWC ) هو SWC-102: إصدار المترجم قديم.
في عملية تطوير الأمان الداخلي، نحث فريق التطوير على ترقية إصدار مترجم Solidity، وندعو إلى إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.
لكن لا داعي للقلق المفرط بشأن ثغرات المترجم، فمعظم ثغرات المترجم يتم تفعيلها فقط في أنماط رموز معينة. العقود التي تم تجميعها باستخدام إصدارات مترجم تحتوي على ثغرات ليست بالضرورة معرضة لمخاطر أمنية، ويجب تقييم التأثير الأمني الفعلي بناءً على حالة المشروع المحدد.
بعض الموارد المفيدة:
تنبيهات الأمان التي يصدرها فريق Solidity بانتظام:
قائمة الأخطاء التي يتم تحديثها بانتظام في مستودع Solidity الرسمي:
قائمة أخطاء المترجمين لكل إصدار:
على Etherscan ، علامة مثلث التعجب في الزاوية اليمنى العليا من صفحة العقد > الكود يمكن أن تشير إلى الثغرات الأمنية في المترجم الحالي.
ملخص
تستعرض هذه المقالة مفهوم ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تنشأ في بيئة تطوير Ethereum، وتقدم نصائح أمنية عملية للمطورين وموظفي الأمان. على الرغم من أن ثغرات المترجم ليست شائعة، إلا أن تأثيرها قد يكون خطيرًا، مما يستدعي اهتمام المطورين وموظفي الأمان.
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تسجيلات الإعجاب 22
أعجبني
22
7
إعادة النشر
مشاركة
تعليق
0/400
fork_in_the_road
· 07-19 10:48
هل يمكن أن تكون هناك ثغرات في المترجم؟ لماذا كل هذا الذعر!
شاهد النسخة الأصليةرد0
gas_fee_therapist
· 07-19 08:57
هذه الثغرة مكتوبة بوضوح!
شاهد النسخة الأصليةرد0
GateUser-75ee51e7
· 07-18 18:19
وجود خطأ برمجي أفضل من التعدين
شاهد النسخة الأصليةرد0
MetaverseHobo
· 07-16 19:40
هل واجه المترجم مشاكل أيضًا؟ هذه الفوضى تسببت في ارتباك.
شاهد النسخة الأصليةرد0
DeepRabbitHole
· 07-16 19:39
يا إلهي، هناك العديد من الثغرات ولا يزالون يلعبون قفل المركز؟
شاهد النسخة الأصليةرد0
GasWaster
· 07-16 19:37
هل يوجد ثغرات في المترجم أيضًا؟ yyds
شاهد النسخة الأصليةرد0
ForkTongue
· 07-16 19:23
استغلال ثغرات البطاقات للحصول على المال هو الأكثر موثوقية.
تحليل ثغرات مترجم Solidity: التأثيرات، الحالات واستراتيجيات التعامل
تحليل ثغرات مترجم Solidity واستراتيجيات التعامل معها
المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة. إنه برنامج حاسوبي، وظيفته تحويل الشيفرة المصدرية للغات البرمجة عالية المستوى التي يسهل على الإنسان فهمها وكتابتها إلى تعليمات قابلة للتنفيذ من قبل وحدة المعالجة المركزية أو آلة بايت كود.
عادةً ما يكون معظم المطورين وخبراء الأمان مهتمين بأمان كود تطبيقات البرامج، لكن قد يتجاهلون أمان المترجم نفسه. في الواقع، يمكن أن يحتوي المترجم، كبرنامج حاسوبي، على ثغرات أمنية، وقد تؤدي الثغرات الأمنية الناتجة عن المترجم في بعض الحالات إلى مخاطر أمان خطيرة. على سبيل المثال، خلال عملية تجميع وتحليل وتنفيذ كود Javascript في الواجهة الأمامية، قد يؤدي وجود ثغرة في محرك تحليل Javascript إلى استغلال المهاجمين الثغرة لتحقيق تنفيذ كود عن بُعد، مما يمكنهم في النهاية من السيطرة على متصفح الضحية أو حتى نظام التشغيل. أظهرت بعض الدراسات أن أخطاء مترجم Clang C++ يمكن أن تؤدي أيضًا إلى تنفيذ كود عن بُعد وما إلى ذلك من عواقب وخيمة.
لم يكن مترجم Solidity استثناءً، وفقًا لتنبيه الأمان من فريق تطوير Solidity، توجد ثغرات أمان في عدة إصدارات مختلفة من مترجم Solidity.
ثغرة مترجم سوليديتي
تتمثل وظيفة مترجم Solidity في تحويل كود العقد الذكي الذي كتبه المطورون إلى كود تعليمات آلة Ethereum (EVM)، ويتم تحميل هذه تعليمات EVM من خلال معاملات مدمجة إلى Ethereum، وأخيراً يتم解析ها وتنفيذها بواسطة EVM.
يجب التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. تشير ثغرات EVM إلى الثغرات الأمنية التي تحدث أثناء تنفيذ التعليمات في الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي كود إلى الإيثريوم، فإن هذا الكود سيتم تنفيذه في كل برنامج عميل P2P للإيثريوم، وإذا كانت هناك ثغرات أمنية في EVM، فإن ذلك سيؤثر على الشبكة بأكملها، مما قد يتسبب في رفض الخدمة (DoS) أو حتى يؤدي إلى سيطرة كاملة للمهاجمين على السلسلة. ومع ذلك، نظرًا لأن تصميم EVM بسيط نسبيًا، وأن الكود الأساسي لا يتم تحديثه بشكل متكرر، فإن احتمال ظهور المشكلات المذكورة أعلاه منخفض نسبيًا.
ثغرات مترجم Solidity تشير إلى وجود ثغرات أثناء تحويل المترجم لغة Solidity إلى كود EVM. على عكس السيناريوهات التي يتم فيها تجميع وتشغيل Javascript على أجهزة الكمبيوتر العميلة للمستخدمين، فإن عملية تجميع Solidity تتم فقط على أجهزة الكمبيوتر الخاصة بمطوري العقود الذكية، ولا يتم تشغيلها على شبكة Ethereum. لذلك، فإن ثغرات مترجم Solidity لن تؤثر مباشرة على شبكة Ethereum نفسها.
تتمثل إحدى الأضرار الرئيسية لثغرات مترجم سوليدتي في أنها قد تؤدي إلى عدم تطابق كود EVM الناتج مع توقعات مطوري العقود الذكية. نظرًا لأن العقود الذكية على إيثريوم تتعلق عادةً بأصول العملات المشفرة للمستخدمين، فإن أي خطأ ينتج عن المترجم في العقود الذكية يمكن أن يتسبب في خسارة أصول المستخدمين، مما يؤدي إلى عواقب وخيمة.
قد تركز المطورون ومراجعي العقود على مشكلات تنفيذ منطق كود العقد، بالإضافة إلى مشكلات الأمان على مستوى Solidity مثل إعادة الإدخال وتجاوز الأعداد الصحيحة. ومع ذلك، من الصعب جداً اكتشاف ثغرات مترجم Solidity فقط من خلال تدقيق منطق شفرة العقد المصدر. تحتاج إلى تحليل مشترك بين إصدار المترجم المحدد وأنماط الشفرة المحددة لتحديد ما إذا كانت العقود الذكية تتأثر بثغرات المترجم.
مثال على ثغرات مترجم Solidity
تظهر الأمثلة الحقيقية التالية لحالات ثغرات مترجم Solidity أشكال الثغرات في مترجم Solidity وأسبابها وأضرارها.
SOL-2016-9 تخزين نظيف للبايت عالي الطلب
توجد هذه الثغرة في إصدارات أقدم من مجمع Solidity (≥0.1.6 <0.4.4).
اعتبر الكود التالي:
صلابة العقد C { uint32 أ = 0x12345678; uint16 ب = 0x1234 ؛
وظيفة f() عامة { a = a + 1; }
ترجع الدالة run() العرض العام (uint16) { ارجع b; } }
لم يتم تعديل المتغير storage b على الإطلاق، لذلك يجب أن تعيد الدالة run() القيمة الافتراضية 0. لكن في الواقع، في الكود الناتج عن إصدار المترجم الذي يحتوي على ثغرة، ستعيد الدالة run() القيمة 1.
من الصعب على المطورين العاديين اكتشاف الأخطاء الموجودة في الشيفرة المذكورة أعلاه من خلال مراجعة الشيفرة البسيطة دون فهم ثغرات المترجم. الشيفرة المذكورة أعلاه هي مجرد مثال بسيط، وبالتالي لن تسبب ضرراً خطيراً بشكل خاص. ولكن إذا تم استخدام المتغير b للتحقق من الأذونات، أو محاسبة الأصول، فإن هذا الاختلاف عن المتوقع قد يؤدي إلى عواقب وخيمة جداً.
سبب ظهور الظواهر الشاذة المذكورة أعلاه هو أن EVM تستخدم آلة افتراضية قائمة على المكدس، حيث كل عنصر في المكدس بحجم 32 بايت ( أي بحجم متغير uint256 ). من ناحية أخرى، كل فتحة في التخزين الأساسي storage أيضًا بحجم 32 بايت. بينما تدعم لغة Solidity أنواع بيانات مختلفة مثل uint32 وأي نوع آخر أقل من 32 بايت، عند معالجة مثل هذه الأنواع من المتغيرات، يحتاج المترجم إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا (clean up) لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما يحدثoverflow في الجمع، لم يقم المترجم بتنظيف الأجزاء العليا من النتيجة بشكل صحيح، مما أدى إلى كتابة البت 1 في الأجزاء العليا في التخزين، مما أدى في النهاية إلى الكتابة فوق المتغير a وتعديل قيمة المتغير b إلى 1.
SOL-2022-4 آثار ذاكرة التجميعات المضمنة
توجد هذه الثغرة في المترجمين من الإصدارات >=0.8.13 <0.8.15. أثناء تحويل لغة سوليديتي إلى كود EVM، لا يقوم مترجم سوليديتي ببساطة بترجمة النص. بل إنه يقوم أيضًا بتحليل عميق لتدفق التحكم والبيانات، ويحقق مجموعة متنوعة من عمليات تحسين الترجمة لتقليل حجم الكود الناتج، وتحسين استهلاك الغاز أثناء عملية التنفيذ. تعتبر هذه الأنواع من عمليات التحسين شائعة في مترجمات العديد من اللغات عالية المستوى، ولكن نظرًا لتعقيد الحالات التي يجب أخذها في الاعتبار، فإنها عرضة لظهور أخطاء أو ثغرات أمنية.
اعتبر الشيفرة التالية:
السوليديتي العقد C { وظيفة f() العوائد العامة النقية (uint256) { التجميع { mstore(0 ، 0x42) } uint256 x; التجميع { x := mload(0) } عودة x; } }
تأتي ثغرة الكود المذكور من عمليات تحسين التجميع. في بعض الحالات، إذا كان هناك كود يقوم بتعديل البيانات في موضع الذاكرة 0 داخل الدالة، ولكن لم يتم استخدام هذه البيانات في أي مكان لاحق، يمكن فعليًا إزالة كود تعديل الذاكرة 0 مباشرة، مما يوفر الغاز، دون التأثير على منطق البرنامج اللاحق.
استراتيجية التحسين هذه ليست بها مشكلة، لكن في تنفيذ كود مترجم Solidity المحدد، يتم تطبيق مثل هذه التحسينات فقط داخل كتلة assembly واحدة. في الشيفرة المثال المذكورة أعلاه، تتم الكتابة والوصول إلى الذاكرة 0 في كتلتين assembly مختلفتين، بينما يقوم المترجم بتحليل وتحسين كتلة assembly بشكل منفصل فقط. نظرًا لأنه لا توجد أي عمليات قراءة بعد كتابة الذاكرة 0 في الكتلة assembly الأولى، يتم تحديد أن تعليمات الكتابة هذه زائدة، وسيتم إزالة هذه التعليمات، مما يؤدي إلى حدوث خطأ. في النسخة التي تحتوي على الثغرة، ستعيد الدالة f( القيمة 0، بينما يجب أن تعيد الشيفرة المذكورة أعلاه القيمة الصحيحة 0x42.
) SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup
تؤثر هذه الثغرة على المترجمات من الإصدار >= 0.5.8 إلى < 0.8.16. اعتبر الكود التالي:
صلابة العقد C { الدالة f###bytes بيانات الاتصال data( عوائد نقية خارجية )bytes memory( { ذاكرة bytes4) أ = [bytes4[1]data(] ؛ إرجاع abi.encode019283746574839201a); } }
في الظروف العادية، يجب أن تُرجع الشيفرة أعلاه المتغير a كـ "aaaa". ولكن في النسخة التي تحتوي على ثغرات، ستُرجع سلسلة فارغة "".
سبب هذا الثغرة هو أن Solidity عند إجراء عملية abi.encode على مصفوفات من نوع calldata، قامت بشكل خاطئ بتنظيف بعض البيانات، مما أدى إلى تعديل بيانات أخرى مجاورة، مما تسبب في عدم توافق البيانات بعد التشفير وفك التشفير.
من الجدير بالذكر أن Solidity عند إجراء استدعاء خارجي و emit event، تقوم بشكل ضمني بترميز المعلمات باستخدام abi.encode، لذا فإن احتمال ظهور الثغرة المذكورة أعلاه سيكون أعلى مما يتصور.
تم تعديل هذه الثغرة لتصبح سؤالًا مشهورًا في مسابقة الأمان 0ctf 2022، حيث عرضت تأثير ثغرات المجمع على العقود الذكية في سيناريوهات التطوير الحقيقية.
نصائح الأمان
بالنسبة لتهديدات ثغرات مترجم Solidity والتعامل معها، يمكن تقديم الاقتراحات التالية:
إلى المطورين:
استخدم إصدارًا أحدث من مترجم Solidity. على الرغم من أن الإصدارات الجديدة قد تقدم مشكلات أمان جديدة، إلا أن المشكلات المعروفة عادةً ما تكون أقل من الإصدارات القديمة.
تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم ستؤدي إلى نتائج تنفيذ الكود غير متوافقة مع التوقعات. من الصعب اكتشاف هذه الأنواع من المشاكل من خلال مراجعة الكود، لكنها تظهر بسهولة في مرحلة الاختبار. لذلك، فإن زيادة تغطية الكود يمكن أن تتجنب هذه المشاكل إلى أقصى حد.
حاول تجنب استخدام التجميع الداخلي، والترميز وفك الترميز المعقد لهيكلية البيانات متعددة الأبعاد، وما إلى ذلك من العمليات المعقدة. تجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى عندما لا تكون هناك حاجة واضحة. ترتبط معظم الثغرات بالعمليات مثل التجميع الداخلي، ومشفرات ABI. من الأرجح أن يظهر أخطاء في المترجم عند التعامل مع ميزات اللغة المعقدة. من ناحية أخرى، قد يقع المطورون في أخطاء عند استخدام الميزات الجديدة، مما يؤدي إلى مشاكل أمان.
إلى موظفي الأمن:
عند إجراء تدقيق أمان لرمز Solidity، لا تغفل عن المخاطر الأمنية التي قد يقدمها مترجم Solidity. العنصر المقابل في تصنيف نقاط الضعف للعقود الذكية ( SWC ) هو SWC-102: إصدار المترجم قديم.
في عملية تطوير الأمان الداخلي، نحث فريق التطوير على ترقية إصدار مترجم Solidity، وندعو إلى إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.
لكن لا داعي للقلق المفرط بشأن ثغرات المترجم، فمعظم ثغرات المترجم يتم تفعيلها فقط في أنماط رموز معينة. العقود التي تم تجميعها باستخدام إصدارات مترجم تحتوي على ثغرات ليست بالضرورة معرضة لمخاطر أمنية، ويجب تقييم التأثير الأمني الفعلي بناءً على حالة المشروع المحدد.
بعض الموارد المفيدة:
تنبيهات الأمان التي يصدرها فريق Solidity بانتظام:
قائمة الأخطاء التي يتم تحديثها بانتظام في مستودع Solidity الرسمي:
قائمة أخطاء المترجمين لكل إصدار:
على Etherscan ، علامة مثلث التعجب في الزاوية اليمنى العليا من صفحة العقد > الكود يمكن أن تشير إلى الثغرات الأمنية في المترجم الحالي.
ملخص
تستعرض هذه المقالة مفهوم ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تنشأ في بيئة تطوير Ethereum، وتقدم نصائح أمنية عملية للمطورين وموظفي الأمان. على الرغم من أن ثغرات المترجم ليست شائعة، إلا أن تأثيرها قد يكون خطيرًا، مما يستدعي اهتمام المطورين وموظفي الأمان.