تحليل ثغرات مترجم Solidity واستراتيجيات التعامل معها
المترجم هو أحد المكونات الأساسية في أنظمة الكمبيوتر الحديثة. هو برنامج كمبيوتر خاص مسؤول عن تحويل رمز البرمجة عالي المستوى الذي يسهل على البشر فهمه وكتابته إلى تعليمات يمكن لوحدة المعالجة المركزية أو آلة بايت كود تنفيذها.
على الرغم من أن معظم المطورين وخبراء الأمان غالبًا ما يركزون على أمان كود التطبيق، إلا أن أمان المترجم نفسه لا يمكن تجاهله. باعتباره نوعًا من برامج الكمبيوتر، قد يحتوي المترجم أيضًا على ثغرات أمان، وهذه الثغرات قد تؤدي في بعض الحالات إلى مخاطر أمان خطيرة. على سبيل المثال، عند تجميع وتحليل كود جافا سكريبت الأمامي، قد تؤدي ثغرات في محرك تحليل جافا سكريبت إلى استغلال المهاجمين للثغرات عند زيارة المستخدمين لمواقع الويب الضارة، مما يؤدي في النهاية إلى تنفيذ تعليمات برمجية عن بُعد والسيطرة على متصفح الضحية أو حتى نظام التشغيل بالكامل.
لا يُستثنى مُجمع Solidity من ذلك، حيث توجد ثغرات أمان في إصدارات مختلفة متعددة.
ثغرة في مترجم Solidity
الوظيفة الرئيسية لمجمع Solidity هي تحويل كود العقود الذكية الذي يكتبه المطورون إلى كود تعليمات يمكن تنفيذه بواسطة الآلة الافتراضية على الإيثيريوم (EVM). يتم تحميل كود تعليمات EVM هذا إلى شبكة الإيثيريوم من خلال المعاملات، ويتم تفسيره وتنفيذه في النهاية بواسطة EVM.
من المهم ملاحظة أن ثغرات مترجم Solidity تختلف عن ثغرات EVM نفسها. تشير ثغرات EVM إلى المشكلات الأمنية التي تحدث أثناء تنفيذ التعليمات بواسطة الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي رمز إلى شبكة Ethereum، سيتم تشغيل هذه الرموز في النهاية في كل برنامج عميل P2P على Ethereum، وإذا كانت هناك ثغرات أمنية في EVM، فقد تؤثر على شبكة Ethereum بأكملها، مما يسبب رفض الخدمة (DoS) أو حتى يؤدي إلى سيطرة المهاجمين على سلسلة الكتل بأكملها. ومع ذلك، نظرًا لأن تصميم EVM بسيط نسبيًا، وكودها الأساسي لا يتم تحديثه بشكل متكرر، فإن احتمال حدوث مثل هذه المشكلات يكون منخفضًا.
تعتبر ثغرات مترجم Solidity هي المشاكل التي تحدث أثناء تحويل كود Solidity إلى كود EVM. على عكس حالة تشغيل Javascript في متصفح على جهاز الكمبيوتر الخاص بالمستخدم، تتم عملية ترجمة Solidity فقط على جهاز الكمبيوتر لمطوري العقود الذكية، ولا يتم تنفيذها على شبكة Ethereum. لذلك، فإن ثغرات مترجم Solidity لن تؤثر مباشرة على شبكة Ethereum نفسها.
تتمثل إحدى المخاطر الرئيسية لثغرات مترجم Solidity في أنها قد تؤدي إلى توليد كود EVM لا يتوافق مع توقعات مطوري العقود الذكية. نظرًا لأن العقود الذكية على Ethereum غالبًا ما تتعلق بأصول العملات المشفرة للمستخدمين، فإن أي خطأ في العقود الذكية ناتج عن المترجم قد يتسبب في فقدان أصول المستخدمين، مما يؤدي إلى عواقب وخيمة.
قد يركز المطورون ومراجعي العقود على مشكلات تنفيذ منطق شفرة العقد، بالإضافة إلى مشكلات الأمان على مستوى Solidity مثل إعادة الدخول، وتجاوز السعة العددية. ومع ذلك، من الصعب اكتشاف ثغرات مترجم Solidity فقط من خلال مراجعة منطق شفرة العقد المصدرية. من الضروري تحليلها بالاشتراك مع إصدار مترجم معين وأنماط الشفرات المحددة لتحديد ما إذا كانت العقود الذكية تأثرت بثغرات المترجم.
مثال على ثغرة في مترجم Solidity
فيما يلي بعض الأمثلة الحقيقية على ثغرات مترجم Solidity، توضح الأشكال والأسباب والأضرار المحددة.
SOL-2016-9 تخزين بايت مرتفع نظيف
توجد هذه الثغرة في إصدارات سابقة من مترجم Solidity (>=0.1.6 <0.4.4).
فكر في الشيفرة التالية:
سوليديتي
عقد C {
uint32 أ = 0x1234;
uint32 ب = 0 ؛
وظيفة f() عامة {
a += 1;
}
ترجع الدالة run() العرض العام (uint) {
عائد b;
}
}
متغير storage b لم يتعرض لأي تعديل، لذا يجب أن ترجع الدالة run() القيمة الافتراضية 0. ولكن في الكود الذي تم إنشاؤه بواسطة نسخة المترجم المعرضة للثغرات، فإن الدالة run() سترجع فعليًا 1.
يصعب على المطورين العاديين اكتشاف المشكلات الموجودة في الكود أعلاه من خلال مراجعة كود بسيطة. على الرغم من أن هذا المثال بسيط نسبيًا، وقد لا يؤدي إلى عواقب خطيرة بشكل خاص، إلا أنه إذا تم استخدام المتغير b لأغراض حيوية مثل التحقق من الأذونات أو محاسبة الأصول، فإن هذه الحالة غير المتوقعة قد تؤدي إلى مخاطر أمنية خطيرة.
تتمثل جذور هذه المشكلة في استخدام EVM لآلة افتراضية قائمة على المكدس، حيث يكون كل عنصر في المكدس بحجم 32 بايت (أي حجم متغير uint256). كل فتحة في التخزين السفلي storage أيضًا بحجم 32 بايت. تدعم لغة Solidity أنواع البيانات المختلفة التي تقل عن 32 بايت مثل uint32، وعند معالجة المتغيرات من هذه الأنواع، يحتاج المترجم إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما ينتج عن الجمع تجاوز عددي، لم يقم المترجم بتنظيف الأجزاء العليا من النتيجة بشكل صحيح، مما أدى إلى كتابة بتة 1 في الأجزاء العليا في التخزين بعد التجاوز، مما أدى في النهاية إلى الكتابة فوق المتغير b الذي يلي المتغير a، مما غير قيمة المتغير b إلى 1.
SOL-2022-4 تأثيرات الذاكرة في التجميع الداخلي
توجد الثغرة في المترجم بالإصدارات من >=0.8.13 إلى <0.8.15. اعتبر الكود التالي:
صلابة
العقد C {
وظيفة f() العوائد العامة النقية (uint) {
التجميع {
mstore(0 ، 0x42)
}
uint x;
التجميع {
x := mload(0)
}
عودة x ؛
}
}
لا يقتصر عمل مترجم Solidity على ترجمة لغة Solidity إلى تعليمات EVM فحسب، بل يتضمن أيضًا تحليلًا عميقًا لتدفق التحكم والبيانات، وتنفيذ مجموعة متنوعة من عمليات تحسين الترجمة، لتقليل حجم التعليمات البرمجية الناتجة وتحسين استهلاك الغاز أثناء عملية التنفيذ. تعتبر هذه العمليات التحسينية شائعة في المترجمات للغات البرمجة عالية المستوى، ولكن نظرًا للتعقيدات الكثيرة التي يجب أخذها في الاعتبار، هناك احتمال لظهور أخطاء أو ثغرات أمنية.
تعود ثغرات الشيفرة المذكورة إلى هذا النوع من عمليات التحسين. يعتقد المترجم أنه إذا كان هناك كود في دالة معينة يقوم بتعديل البيانات في الموقع 0 من الذاكرة، ولكن لا يوجد أي مكان آخر يستخدم تلك البيانات بعد ذلك، فإنه يمكن إزالة كود تعديل الذاكرة 0 مباشرة، مما يوفر الغاز، ولا يؤثر على منطق البرنامج اللاحق.
هذه الاستراتيجية التحسينية ليست لديها مشاكل في حد ذاتها، ولكن في تنفيذ كود المترجم Solidity المحدد، يتم تطبيق هذه الأنواع من التحسينات فقط على كتلة assembly واحدة. بالنسبة لكود PoC المذكور أعلاه، فإن الكتابة والوصول إلى الذاكرة 0 موجودان في كتلتين assembly مختلفتين، بينما قام المترجم بتحليل وتحسين فقط كتلة assembly المنفصلة. نظرًا لأنه لا توجد عمليات قراءة بعد الكتابة إلى الذاكرة 0 في الكتلة assembly الأولى، فقد تم اعتبار هذه التعليمات الكتابية زائدة وسيتم إزالتها، مما يؤدي إلى ظهور خطأ. في الإصدار المصاب، ستقوم الدالة f() بإرجاع القيمة 0، بينما القيمة الصحيحة التي يجب أن ترجعها الكود المذكور أعلاه هي 0x42.
تؤثر الثغرة على المترجمين من الإصدار >= 0.5.8 < 0.8.16. اعتبر الكود التالي:
صلابة
العقد C {
الدالة f(string[1] بيانات المكالمات a) عوائد نقية خارجية (string memory) {
إرجاع abi.decode019283746574839201abi.encode(a( ، )string([1])).
}
}
في الظروف العادية، يجب أن تكون قيمة المتغير a التي ترجعها الشفرة أعلاه هي "aaaa". ولكن في النسخة المعيبة، ستعيد سلسلة فارغة "".
سبب هذه الثغرة هو أن Solidity قام بعملية abi.encode لمصفوفات من نوع calldata بطريقة خاطئة، حيث تم تنظيف بعض البيانات بشكل غير صحيح، مما أدى إلى تعديل بيانات أخرى مجاورة، وبالتالي تسبب في عدم تطابق البيانات بعد الترميز وفك الترميز.
من المهم ملاحظة أن Solidity عند إجراء استدعاء خارجي و emit event، يقوم ضمنيًا بتشفير المعلمات باستخدام abi.encode، وبالتالي فإن احتمال ظهور ثغرة الشيفرة المذكورة أعلاه سيكون أعلى مما قد يتوقعه الشخص بشكل مباشر.
بعد تحليل نموذج تهديد ثغرات مترجم Solidity واستعراض الثغرات التاريخية، نقدم للمطورين وفرق الأمان الاقتراحات التالية.
) للمطورين:
استخدم إصداراً أحدث من مجمع Solidity. على الرغم من أن الإصدارات الجديدة قد تقدم مشكلات أمنية جديدة، إلا أن المشكلات الأمنية المعروفة عادةً ما تكون أقل في الإصدارات القديمة.
تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم تؤدي إلى نتائج تنفيذ الكود غير متوافقة مع التوقعات. هذه المشاكل يصعب اكتشافها من خلال مراجعة الكود، لكن من السهل الكشف عنها في مرحلة الاختبار. لذلك، من خلال زيادة نسبة تغطية الكود، يمكن تجنب مثل هذه المشاكل إلى أقصى حد.
حاول تجنب استخدام التجميع المضمن، والترميز وفك الترميز المعقد لمصفوفات متعددة الأبعاد والهياكل المعقدة، وتجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى دون وجود حاجة واضحة. وفقًا لتمحيص الثغرات التاريخية، فإن معظم الثغرات مرتبطة بالتجميع المضمن، وعمليات ترميز ABI وغيرها. من الأسهل أن تظهر الأخطاء البرمجية عند معالجة ميزات اللغة المعقدة. من ناحية أخرى، قد يقع المطورون في أخطاء استخدام عند استخدام الميزات الجديدة، مما يؤدي إلى مشاكل في الأمان.
إلى موظفي الأمن:
عند إجراء تدقيق أمان لشفرة Solidity، لا تتجاهل المخاطر الأمنية التي قد يقدمها مترجم Solidity. تشير النقطة المقابلة في تصنيف ضعف العقود الذكية ###SWC( إلى SWC-102: إصدار المترجم قديم.
في عملية تطوير SDL الداخلية، يُحث فريق التطوير على ترقية إصدار مترجم Solidity، ويمكن النظر في إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.
لكن لا داعي للذعر المفرط من ثغرات المترجم، حيث إن معظم ثغرات المترجم يتم تفعيلها فقط في أنماط معينة من الشفرة، وليس من الضروري أن توجد مخاطر أمان عند استخدام نسخة مترجم تحتوي على ثغرات في العقود، بل يجب تقييم التأثير الأمني الفعلي بناءً على حالة المشروع.
الموارد العملية
المقالات التحذيرية الأمنية التي تنشرها فريق Solidity بشكل دوري
قائمة الأخطاء التي يتم تحديثها بانتظام في مستودع سوليديتي الرسمي
قائمة الأخطاء في المترجمات المختلفة. يمكن استخدام ذلك لإدخال فحص تلقائي لإصدار المترجم أثناء عملية CI/CD، للإشارة إلى الثغرات الأمنية الموجودة في الإصدار الحالي.
الكود تشير إلى الثغرات الأمنية الموجودة في إصدار المترجم الحالي.
تبدأ هذه المقالة بمفهوم الأساسيات للمترجم، وتقدم مقدمة عن ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تنتج عنها في بيئة تطوير Ethereum الفعلية، وأخيرًا تقدم عددًا من النصائح الأمنية العملية للمطورين وموظفي الأمان. من خلال فهم هذه الثغرات واتخاذ تدابير وقائية مناسبة، يمكننا حماية أمان العقود الذكية بشكل أفضل وتقليل مخاطر فقدان الأصول المحتملة.
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تسجيلات الإعجاب 12
أعجبني
12
6
مشاركة
تعليق
0/400
0xLuckbox
· منذ 9 س
ثغرات المنطق مؤذية حقًا، سأذهب الآن.
شاهد النسخة الأصليةرد0
LidoStakeAddict
· 07-30 09:56
تجاوزت الحدود يجب تعديل الكود
شاهد النسخة الأصليةرد0
StablecoinArbitrageur
· 07-30 09:26
*يعدل النظارات* همم... من الناحية الإحصائية، فإن مخاطر المجمعات تحتسب بشكل منخفض بشكل كبير في حسابات القيمة الإجمالية المقفلة في التمويل اللامركزي.
شاهد النسخة الأصليةرد0
BoredStaker
· 07-30 09:24
متى يمكننا التحدث بلغة البشر!
شاهد النسخة الأصليةرد0
ArbitrageBot
· 07-30 09:24
هل سنعود مرة أخرى إلى حفرة تجميع المترجم؟
شاهد النسخة الأصليةرد0
APY追逐者
· 07-30 09:15
تذكرت ثغرة المترجم فقط عندما كانت رسوم الغاز مرتفعة.
تحليل ثغرات مترجم Solidity وممارسات الوقاية الأمنية
تحليل ثغرات مترجم Solidity واستراتيجيات التعامل معها
المترجم هو أحد المكونات الأساسية في أنظمة الكمبيوتر الحديثة. هو برنامج كمبيوتر خاص مسؤول عن تحويل رمز البرمجة عالي المستوى الذي يسهل على البشر فهمه وكتابته إلى تعليمات يمكن لوحدة المعالجة المركزية أو آلة بايت كود تنفيذها.
على الرغم من أن معظم المطورين وخبراء الأمان غالبًا ما يركزون على أمان كود التطبيق، إلا أن أمان المترجم نفسه لا يمكن تجاهله. باعتباره نوعًا من برامج الكمبيوتر، قد يحتوي المترجم أيضًا على ثغرات أمان، وهذه الثغرات قد تؤدي في بعض الحالات إلى مخاطر أمان خطيرة. على سبيل المثال، عند تجميع وتحليل كود جافا سكريبت الأمامي، قد تؤدي ثغرات في محرك تحليل جافا سكريبت إلى استغلال المهاجمين للثغرات عند زيارة المستخدمين لمواقع الويب الضارة، مما يؤدي في النهاية إلى تنفيذ تعليمات برمجية عن بُعد والسيطرة على متصفح الضحية أو حتى نظام التشغيل بالكامل.
لا يُستثنى مُجمع Solidity من ذلك، حيث توجد ثغرات أمان في إصدارات مختلفة متعددة.
ثغرة في مترجم Solidity
الوظيفة الرئيسية لمجمع Solidity هي تحويل كود العقود الذكية الذي يكتبه المطورون إلى كود تعليمات يمكن تنفيذه بواسطة الآلة الافتراضية على الإيثيريوم (EVM). يتم تحميل كود تعليمات EVM هذا إلى شبكة الإيثيريوم من خلال المعاملات، ويتم تفسيره وتنفيذه في النهاية بواسطة EVM.
من المهم ملاحظة أن ثغرات مترجم Solidity تختلف عن ثغرات EVM نفسها. تشير ثغرات EVM إلى المشكلات الأمنية التي تحدث أثناء تنفيذ التعليمات بواسطة الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي رمز إلى شبكة Ethereum، سيتم تشغيل هذه الرموز في النهاية في كل برنامج عميل P2P على Ethereum، وإذا كانت هناك ثغرات أمنية في EVM، فقد تؤثر على شبكة Ethereum بأكملها، مما يسبب رفض الخدمة (DoS) أو حتى يؤدي إلى سيطرة المهاجمين على سلسلة الكتل بأكملها. ومع ذلك، نظرًا لأن تصميم EVM بسيط نسبيًا، وكودها الأساسي لا يتم تحديثه بشكل متكرر، فإن احتمال حدوث مثل هذه المشكلات يكون منخفضًا.
تعتبر ثغرات مترجم Solidity هي المشاكل التي تحدث أثناء تحويل كود Solidity إلى كود EVM. على عكس حالة تشغيل Javascript في متصفح على جهاز الكمبيوتر الخاص بالمستخدم، تتم عملية ترجمة Solidity فقط على جهاز الكمبيوتر لمطوري العقود الذكية، ولا يتم تنفيذها على شبكة Ethereum. لذلك، فإن ثغرات مترجم Solidity لن تؤثر مباشرة على شبكة Ethereum نفسها.
تتمثل إحدى المخاطر الرئيسية لثغرات مترجم Solidity في أنها قد تؤدي إلى توليد كود EVM لا يتوافق مع توقعات مطوري العقود الذكية. نظرًا لأن العقود الذكية على Ethereum غالبًا ما تتعلق بأصول العملات المشفرة للمستخدمين، فإن أي خطأ في العقود الذكية ناتج عن المترجم قد يتسبب في فقدان أصول المستخدمين، مما يؤدي إلى عواقب وخيمة.
قد يركز المطورون ومراجعي العقود على مشكلات تنفيذ منطق شفرة العقد، بالإضافة إلى مشكلات الأمان على مستوى Solidity مثل إعادة الدخول، وتجاوز السعة العددية. ومع ذلك، من الصعب اكتشاف ثغرات مترجم Solidity فقط من خلال مراجعة منطق شفرة العقد المصدرية. من الضروري تحليلها بالاشتراك مع إصدار مترجم معين وأنماط الشفرات المحددة لتحديد ما إذا كانت العقود الذكية تأثرت بثغرات المترجم.
مثال على ثغرة في مترجم Solidity
فيما يلي بعض الأمثلة الحقيقية على ثغرات مترجم Solidity، توضح الأشكال والأسباب والأضرار المحددة.
SOL-2016-9 تخزين بايت مرتفع نظيف
توجد هذه الثغرة في إصدارات سابقة من مترجم Solidity (>=0.1.6 <0.4.4).
فكر في الشيفرة التالية:
سوليديتي عقد C { uint32 أ = 0x1234; uint32 ب = 0 ؛ وظيفة f() عامة { a += 1; } ترجع الدالة run() العرض العام (uint) { عائد b; } }
متغير storage b لم يتعرض لأي تعديل، لذا يجب أن ترجع الدالة run() القيمة الافتراضية 0. ولكن في الكود الذي تم إنشاؤه بواسطة نسخة المترجم المعرضة للثغرات، فإن الدالة run() سترجع فعليًا 1.
يصعب على المطورين العاديين اكتشاف المشكلات الموجودة في الكود أعلاه من خلال مراجعة كود بسيطة. على الرغم من أن هذا المثال بسيط نسبيًا، وقد لا يؤدي إلى عواقب خطيرة بشكل خاص، إلا أنه إذا تم استخدام المتغير b لأغراض حيوية مثل التحقق من الأذونات أو محاسبة الأصول، فإن هذه الحالة غير المتوقعة قد تؤدي إلى مخاطر أمنية خطيرة.
تتمثل جذور هذه المشكلة في استخدام EVM لآلة افتراضية قائمة على المكدس، حيث يكون كل عنصر في المكدس بحجم 32 بايت (أي حجم متغير uint256). كل فتحة في التخزين السفلي storage أيضًا بحجم 32 بايت. تدعم لغة Solidity أنواع البيانات المختلفة التي تقل عن 32 بايت مثل uint32، وعند معالجة المتغيرات من هذه الأنواع، يحتاج المترجم إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما ينتج عن الجمع تجاوز عددي، لم يقم المترجم بتنظيف الأجزاء العليا من النتيجة بشكل صحيح، مما أدى إلى كتابة بتة 1 في الأجزاء العليا في التخزين بعد التجاوز، مما أدى في النهاية إلى الكتابة فوق المتغير b الذي يلي المتغير a، مما غير قيمة المتغير b إلى 1.
SOL-2022-4 تأثيرات الذاكرة في التجميع الداخلي
توجد الثغرة في المترجم بالإصدارات من >=0.8.13 إلى <0.8.15. اعتبر الكود التالي:
صلابة العقد C { وظيفة f() العوائد العامة النقية (uint) { التجميع { mstore(0 ، 0x42) } uint x; التجميع { x := mload(0) } عودة x ؛ } }
لا يقتصر عمل مترجم Solidity على ترجمة لغة Solidity إلى تعليمات EVM فحسب، بل يتضمن أيضًا تحليلًا عميقًا لتدفق التحكم والبيانات، وتنفيذ مجموعة متنوعة من عمليات تحسين الترجمة، لتقليل حجم التعليمات البرمجية الناتجة وتحسين استهلاك الغاز أثناء عملية التنفيذ. تعتبر هذه العمليات التحسينية شائعة في المترجمات للغات البرمجة عالية المستوى، ولكن نظرًا للتعقيدات الكثيرة التي يجب أخذها في الاعتبار، هناك احتمال لظهور أخطاء أو ثغرات أمنية.
تعود ثغرات الشيفرة المذكورة إلى هذا النوع من عمليات التحسين. يعتقد المترجم أنه إذا كان هناك كود في دالة معينة يقوم بتعديل البيانات في الموقع 0 من الذاكرة، ولكن لا يوجد أي مكان آخر يستخدم تلك البيانات بعد ذلك، فإنه يمكن إزالة كود تعديل الذاكرة 0 مباشرة، مما يوفر الغاز، ولا يؤثر على منطق البرنامج اللاحق.
هذه الاستراتيجية التحسينية ليست لديها مشاكل في حد ذاتها، ولكن في تنفيذ كود المترجم Solidity المحدد، يتم تطبيق هذه الأنواع من التحسينات فقط على كتلة assembly واحدة. بالنسبة لكود PoC المذكور أعلاه، فإن الكتابة والوصول إلى الذاكرة 0 موجودان في كتلتين assembly مختلفتين، بينما قام المترجم بتحليل وتحسين فقط كتلة assembly المنفصلة. نظرًا لأنه لا توجد عمليات قراءة بعد الكتابة إلى الذاكرة 0 في الكتلة assembly الأولى، فقد تم اعتبار هذه التعليمات الكتابية زائدة وسيتم إزالتها، مما يؤدي إلى ظهور خطأ. في الإصدار المصاب، ستقوم الدالة f() بإرجاع القيمة 0، بينما القيمة الصحيحة التي يجب أن ترجعها الكود المذكور أعلاه هي 0x42.
SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup
تؤثر الثغرة على المترجمين من الإصدار >= 0.5.8 < 0.8.16. اعتبر الكود التالي:
صلابة العقد C { الدالة f(string[1] بيانات المكالمات a) عوائد نقية خارجية (string memory) { إرجاع abi.decode019283746574839201abi.encode(a( ، )string([1])). } }
في الظروف العادية، يجب أن تكون قيمة المتغير a التي ترجعها الشفرة أعلاه هي "aaaa". ولكن في النسخة المعيبة، ستعيد سلسلة فارغة "".
سبب هذه الثغرة هو أن Solidity قام بعملية abi.encode لمصفوفات من نوع calldata بطريقة خاطئة، حيث تم تنظيف بعض البيانات بشكل غير صحيح، مما أدى إلى تعديل بيانات أخرى مجاورة، وبالتالي تسبب في عدم تطابق البيانات بعد الترميز وفك الترميز.
من المهم ملاحظة أن Solidity عند إجراء استدعاء خارجي و emit event، يقوم ضمنيًا بتشفير المعلمات باستخدام abi.encode، وبالتالي فإن احتمال ظهور ثغرة الشيفرة المذكورة أعلاه سيكون أعلى مما قد يتوقعه الشخص بشكل مباشر.
![تحليل ثغرات مترجم Solidity وتدابير المواجهة][0]https://img-cdn.gateio.im/webp-social/moments-c97428f89ed62d5ad8551cdb2ba30867.webp(
نصائح الأمان
بعد تحليل نموذج تهديد ثغرات مترجم Solidity واستعراض الثغرات التاريخية، نقدم للمطورين وفرق الأمان الاقتراحات التالية.
) للمطورين:
استخدم إصداراً أحدث من مجمع Solidity. على الرغم من أن الإصدارات الجديدة قد تقدم مشكلات أمنية جديدة، إلا أن المشكلات الأمنية المعروفة عادةً ما تكون أقل في الإصدارات القديمة.
تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم تؤدي إلى نتائج تنفيذ الكود غير متوافقة مع التوقعات. هذه المشاكل يصعب اكتشافها من خلال مراجعة الكود، لكن من السهل الكشف عنها في مرحلة الاختبار. لذلك، من خلال زيادة نسبة تغطية الكود، يمكن تجنب مثل هذه المشاكل إلى أقصى حد.
حاول تجنب استخدام التجميع المضمن، والترميز وفك الترميز المعقد لمصفوفات متعددة الأبعاد والهياكل المعقدة، وتجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى دون وجود حاجة واضحة. وفقًا لتمحيص الثغرات التاريخية، فإن معظم الثغرات مرتبطة بالتجميع المضمن، وعمليات ترميز ABI وغيرها. من الأسهل أن تظهر الأخطاء البرمجية عند معالجة ميزات اللغة المعقدة. من ناحية أخرى، قد يقع المطورون في أخطاء استخدام عند استخدام الميزات الجديدة، مما يؤدي إلى مشاكل في الأمان.
إلى موظفي الأمن:
عند إجراء تدقيق أمان لشفرة Solidity، لا تتجاهل المخاطر الأمنية التي قد يقدمها مترجم Solidity. تشير النقطة المقابلة في تصنيف ضعف العقود الذكية ###SWC( إلى SWC-102: إصدار المترجم قديم.
في عملية تطوير SDL الداخلية، يُحث فريق التطوير على ترقية إصدار مترجم Solidity، ويمكن النظر في إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.
لكن لا داعي للذعر المفرط من ثغرات المترجم، حيث إن معظم ثغرات المترجم يتم تفعيلها فقط في أنماط معينة من الشفرة، وليس من الضروري أن توجد مخاطر أمان عند استخدام نسخة مترجم تحتوي على ثغرات في العقود، بل يجب تقييم التأثير الأمني الفعلي بناءً على حالة المشروع.
الموارد العملية
![تحليل ثغرات مترجم Solidity والتدابير المتخذة])https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(
ملخص
تبدأ هذه المقالة بمفهوم الأساسيات للمترجم، وتقدم مقدمة عن ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تنتج عنها في بيئة تطوير Ethereum الفعلية، وأخيرًا تقدم عددًا من النصائح الأمنية العملية للمطورين وموظفي الأمان. من خلال فهم هذه الثغرات واتخاذ تدابير وقائية مناسبة، يمكننا حماية أمان العقود الذكية بشكل أفضل وتقليل مخاطر فقدان الأصول المحتملة.