المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة، وظيفته تحويل شفرة مصدر لغة البرمجة العالية إلى تعليمات قابلة للتنفيذ بواسطة الكمبيوتر. على الرغم من أن المطورين وفرق الأمان عادة ما يهتمون بأمان شفرة تطبيقات البرامج، إلا أن المترجم نفسه كبرنامج كمبيوتر قد يحتوي أيضًا على ثغرات أمنية، والتي قد تؤدي في بعض الحالات إلى مخاطر أمنية خطيرة.
على سبيل المثال، قد يؤدي استغلال ثغرات في محرك التحليل أثناء تجميع وتنفيذ كود JavaScript إلى تنفيذ كود عن بُعد، مما يمنح المهاجم السيطرة على متصفح الضحية أو حتى نظام التشغيل. كما أظهرت الأبحاث أن أخطاء في مترجم C++ قد تؤدي أيضًا إلى تنفيذ كود عن بُعد وعواقب وخيمة أخرى.
توجد أيضًا ثغرات أمنية في مترجم Solidity. وفقًا لتحذيرات الأمان من فريق التطوير، تم اكتشاف مشكلات أمنية في العديد من إصدارات مترجم Solidity.
وظيفة مترجم Solidity هي تحويل كود العقد الذكي إلى كود تعليمات (EVM) لآلة الإيثريوم الافتراضية. من الضروري التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. تشير ثغرات EVM إلى مشكلات الأمان أثناء تنفيذ الآلة الافتراضية للتعليمات، مما قد يؤثر على شبكة الإيثريوم بأكملها. بينما تشير ثغرات مترجم Solidity إلى المشكلات التي تحدث عند تحويل Solidity إلى كود EVM، والتي لن تؤثر مباشرةً على شبكة الإيثريوم، ولكن قد تؤدي إلى عدم تطابق كود EVM الناتج مع توقعات المطور.
نظرًا لأن العقود الذكية غالبًا ما تتضمن أصول العملات المشفرة للمستخدمين، فإن أي خطأ ناتج عن المترجم قد يؤدي إلى عواقب وخيمة. من الصعب اكتشاف ثغرات المترجم فقط من خلال تدقيق شفرة العقد المصدرية، لذلك يتطلب الأمر تحليلًا يجمع بين إصدار معين وأنماط الشفرة.
فيما يلي من خلال بعض الحالات الحقيقية، يتم عرض الأشكال المحددة لثغرات مترجم Solidity وأسبابها وأضرارها.
SOL-2016-9 تنسيق تخزين بايت عالي النظام
توجد هذه الثغرة في إصدارات سابقة من مترجم Solidity (>=0.1.6 <0.4.4).
ضع في اعتبارك الكود التالي:
سوليديتي
عقد C {
uint32 أ = 0x1234;
uint32 ب = 0 ؛
وظيفة f() عامة {
a += 1;
}
ترجع الدالة run() العرض العام (uint) {
ارجع b;
}
}
المتغير b لم يتغير، يجب أن تُرجع دالة run() القيمة الافتراضية 0. لكن في الشيفرة التي تم إنشاؤها بواسطة مُجمع الإصدار المعيب، ستُرجع run() القيمة 1.
هذا لأنه يستخدم EVM عناصر مكدس بحجم 32 بايت، بينما تدعم Solidity أنواع مثل uint32 التي تقل عن 32 بايت. يحتاج المترجم إلى إجراء عملية مسح للبتات العليا لضمان صحة البيانات. عند حدوث تجاوز في الجمع، لم يقم المترجم بمسح البتات العليا بشكل صحيح، مما أدى إلى كتابة بتة التجاوز 1 في التخزين، مما覆盖 المتغير b.
SOL-2022-4 آثار جانبية للذاكرة في التجميع المضمن
توجد هذه الثغرة في المترجمين من الإصدار >=0.8.13 و <0.8.15.
اعتبر الكود التالي:
صلابة
العقد C {
وظيفة f() العوائد العامة النقية (uint) {
التجميع {
mstore(0 ، 0x42)
}
uint x;
التجميع {
x := mload(0)
}
إرجاع x;
}
}
يقوم المترجم في عملية التحسين بتحليل تدفق التحكم وتدفق البيانات لتقليل حجم الكود وتحسين استهلاك الغاز. لكن هذا النوع من التحسين قد يؤدي بسهولة إلى ظهور أخطاء.
في هذا المثال، اعتقد المترجم خطأً أن الكتابة إلى الذاكرة 0 في كتلة التجميع الأولى كانت زائدة، فقام بإزالتها، مما أدى إلى عودة الدالة f() بقيمة 0 بدلاً من القيمة الصحيحة 0x42.
SOL-2022-6 تجاوز سعة رأس إعادة ترميز ABI مع تنظيف المصفوفة الثابتة
تؤثر الثغرة على المترجمين من الإصدار >= 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، حيث يقوم بشكل خاطئ بتنظيف بعض البيانات، مما يؤدي إلى تعديل البيانات المجاورة، مما يتسبب في عدم اتساق البيانات بعد الترميز وفك الترميز.
من المهم ملاحظة أن استدعاءات الخارجية وإصدار الأحداث يتم بشكل ضمني باستخدام abi.encode، لذا فإن احتمال ظهور هذا النوع من الثغرات مرتفع.
![تحليل ثغرات مترجم Solidity وإجراءات التعامل معها][0]https://img-cdn.gateio.im/webp-social/moments-c97428f89ed62d5ad8551cdb2ba30867.webp(
نصائح السلامة
إلى المطورين:
استخدام إصدارات أحدث من مجمع Solidity، عادةً ما تكون المشكلات الأمنية المعروفة أقل.
تحسين حالات اختبار الوحدة، وزيادة تغطية الشيفرة، مما يساعد في اكتشاف المشكلات الناجمة عن المترجم.
تجنب استخدام التجميع المضمّن، والتشفير وفك التشفير المعقدين لـ ABI، وما إلى ذلك، ولا تستخدم الميزات الجديدة والوظائف التجريبية بشكل أعمى.
إلى أفراد الأمن:
لا تغفل عن المخاطر التي قد يقدمها المترجم أثناء التدقيق، وفقاً لعنصر الفحص SWC-102.
في عملية SDL، يتم دفع ترقية إصدار المترجم، مع مراعاة إدخال فحص تلقائي.
تقييم التأثير الفعلي لثغرات المترجم، لا داعي للذعر المفرط.
بعض الموارد المفيدة:
مدونة تحذير الأمان الرسمية لـ Solidity
قائمة الأخطاء في مستودع Solidity
قائمة أخطاء المترجمات في الإصدارات المختلفة
تنبيه عن ثغرة في المترجم في صفحة العقد الخاصة بـ Etherscan
![تحليل ثغرات مترجم Solidity وتدابير التعامل معها])https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(
بشكل عام، يمكن أن تؤدي ثغرات مترجم Solidity إلى سلوك فعلي للعقود الذكية لا يتوافق مع التوقعات، ويجب على المطورين وفرق الأمان أن يكونوا حذرين حيال ذلك، واتخاذ التدابير المناسبة لتقليل المخاطر.
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تسجيلات الإعجاب 16
أعجبني
16
5
إعادة النشر
مشاركة
تعليق
0/400
ColdWalletGuardian
· 08-06 10:09
لا يزال يجرؤ على استخدام المترجم القديم، عقول حديدية.
شاهد النسخة الأصليةرد0
LayerZeroHero
· 08-06 02:28
المترجم غير مستقر أيضًا
شاهد النسخة الأصليةرد0
RektRecorder
· 08-03 12:34
هذا خطر للغاية ، عائلتي
شاهد النسخة الأصليةرد0
BearMarketGardener
· 08-03 12:30
المترجم مليء بالثغرات، في لحظة نوم يمكن أن تضيع الأصول.
تحليل ثغرات مترجم Solidity: مخاطر العقود الذكية التي لا يمكن تجاهلها
تحليل ثغرات مترجم سوليديتي وإجراءات التعامل معها
المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة، وظيفته تحويل شفرة مصدر لغة البرمجة العالية إلى تعليمات قابلة للتنفيذ بواسطة الكمبيوتر. على الرغم من أن المطورين وفرق الأمان عادة ما يهتمون بأمان شفرة تطبيقات البرامج، إلا أن المترجم نفسه كبرنامج كمبيوتر قد يحتوي أيضًا على ثغرات أمنية، والتي قد تؤدي في بعض الحالات إلى مخاطر أمنية خطيرة.
على سبيل المثال، قد يؤدي استغلال ثغرات في محرك التحليل أثناء تجميع وتنفيذ كود JavaScript إلى تنفيذ كود عن بُعد، مما يمنح المهاجم السيطرة على متصفح الضحية أو حتى نظام التشغيل. كما أظهرت الأبحاث أن أخطاء في مترجم C++ قد تؤدي أيضًا إلى تنفيذ كود عن بُعد وعواقب وخيمة أخرى.
توجد أيضًا ثغرات أمنية في مترجم Solidity. وفقًا لتحذيرات الأمان من فريق التطوير، تم اكتشاف مشكلات أمنية في العديد من إصدارات مترجم Solidity.
وظيفة مترجم Solidity هي تحويل كود العقد الذكي إلى كود تعليمات (EVM) لآلة الإيثريوم الافتراضية. من الضروري التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. تشير ثغرات EVM إلى مشكلات الأمان أثناء تنفيذ الآلة الافتراضية للتعليمات، مما قد يؤثر على شبكة الإيثريوم بأكملها. بينما تشير ثغرات مترجم Solidity إلى المشكلات التي تحدث عند تحويل Solidity إلى كود EVM، والتي لن تؤثر مباشرةً على شبكة الإيثريوم، ولكن قد تؤدي إلى عدم تطابق كود EVM الناتج مع توقعات المطور.
نظرًا لأن العقود الذكية غالبًا ما تتضمن أصول العملات المشفرة للمستخدمين، فإن أي خطأ ناتج عن المترجم قد يؤدي إلى عواقب وخيمة. من الصعب اكتشاف ثغرات المترجم فقط من خلال تدقيق شفرة العقد المصدرية، لذلك يتطلب الأمر تحليلًا يجمع بين إصدار معين وأنماط الشفرة.
فيما يلي من خلال بعض الحالات الحقيقية، يتم عرض الأشكال المحددة لثغرات مترجم Solidity وأسبابها وأضرارها.
SOL-2016-9 تنسيق تخزين بايت عالي النظام
توجد هذه الثغرة في إصدارات سابقة من مترجم Solidity (>=0.1.6 <0.4.4).
ضع في اعتبارك الكود التالي:
سوليديتي عقد C { uint32 أ = 0x1234; uint32 ب = 0 ؛ وظيفة f() عامة { a += 1; } ترجع الدالة run() العرض العام (uint) { ارجع b; } }
المتغير b لم يتغير، يجب أن تُرجع دالة run() القيمة الافتراضية 0. لكن في الشيفرة التي تم إنشاؤها بواسطة مُجمع الإصدار المعيب، ستُرجع run() القيمة 1.
هذا لأنه يستخدم EVM عناصر مكدس بحجم 32 بايت، بينما تدعم Solidity أنواع مثل uint32 التي تقل عن 32 بايت. يحتاج المترجم إلى إجراء عملية مسح للبتات العليا لضمان صحة البيانات. عند حدوث تجاوز في الجمع، لم يقم المترجم بمسح البتات العليا بشكل صحيح، مما أدى إلى كتابة بتة التجاوز 1 في التخزين، مما覆盖 المتغير b.
SOL-2022-4 آثار جانبية للذاكرة في التجميع المضمن
توجد هذه الثغرة في المترجمين من الإصدار >=0.8.13 و <0.8.15.
اعتبر الكود التالي:
صلابة العقد C { وظيفة f() العوائد العامة النقية (uint) { التجميع { mstore(0 ، 0x42) } uint x; التجميع { x := mload(0) } إرجاع x; } }
يقوم المترجم في عملية التحسين بتحليل تدفق التحكم وتدفق البيانات لتقليل حجم الكود وتحسين استهلاك الغاز. لكن هذا النوع من التحسين قد يؤدي بسهولة إلى ظهور أخطاء.
في هذا المثال، اعتقد المترجم خطأً أن الكتابة إلى الذاكرة 0 في كتلة التجميع الأولى كانت زائدة، فقام بإزالتها، مما أدى إلى عودة الدالة f() بقيمة 0 بدلاً من القيمة الصحيحة 0x42.
SOL-2022-6 تجاوز سعة رأس إعادة ترميز ABI مع تنظيف المصفوفة الثابتة
تؤثر الثغرة على المترجمين من الإصدار >= 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، حيث يقوم بشكل خاطئ بتنظيف بعض البيانات، مما يؤدي إلى تعديل البيانات المجاورة، مما يتسبب في عدم اتساق البيانات بعد الترميز وفك الترميز.
من المهم ملاحظة أن استدعاءات الخارجية وإصدار الأحداث يتم بشكل ضمني باستخدام abi.encode، لذا فإن احتمال ظهور هذا النوع من الثغرات مرتفع.
![تحليل ثغرات مترجم Solidity وإجراءات التعامل معها][0]https://img-cdn.gateio.im/webp-social/moments-c97428f89ed62d5ad8551cdb2ba30867.webp(
نصائح السلامة
إلى المطورين:
إلى أفراد الأمن:
بعض الموارد المفيدة:
![تحليل ثغرات مترجم Solidity وتدابير التعامل معها])https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(
بشكل عام، يمكن أن تؤدي ثغرات مترجم Solidity إلى سلوك فعلي للعقود الذكية لا يتوافق مع التوقعات، ويجب على المطورين وفرق الأمان أن يكونوا حذرين حيال ذلك، واتخاذ التدابير المناسبة لتقليل المخاطر.