تحليل ثغرات مترجم Solidity واستراتيجيات التعامل معها
المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة. إنه برنامج كمبيوتر، وتتمثل وظيفته الرئيسية في تحويل شفرة المصدر بلغة البرمجة عالية المستوى، التي يسهل على البشر فهمها وكتابتها، إلى تعليمات قابلة للتنفيذ من قبل وحدة المعالجة المركزية أو آلة افتراضية للبايت.
غالبًا ما يركز معظم المطورين وموظفي الأمان على أمان كود تطبيقات البرامج، لكن قد يتجاهلون أمان المترجم نفسه. في الواقع، المترجم كبرنامج حاسوبي، يحتوي أيضًا على ثغرات أمنية، وقد تؤدي هذه الثغرات في بعض الحالات إلى مخاطر أمنية خطيرة. على سبيل المثال، أثناء عملية تجميع وتحليل وتنفيذ كود جافا سكريبت في المتصفح، قد تؤدي ثغرات في محرك تحليل جافا سكريبت إلى استغلال المهاجمين للثغرات عندما يصل المستخدمون إلى صفحات الويب الضارة، مما يؤدي في النهاية إلى السيطرة على متصفح الضحية أو حتى نظام التشغيل.
لا يُستثنى مترجم Solidity أيضًا، حيث توجد ثغرات أمنية في عدة إصدارات مختلفة.
ثغرات مترجم Solidity
وظيفة مترجم Solidity هي تحويل كود العقد الذكي الذي كتبه المطورون إلى كود تعليمات (EVM) الخاص بـ Ethereum Virtual Machine، حيث يتم تحميل هذه التعليمات EVM عبر معاملات مدمجة على Ethereum، وأخيرًا يتم تحليلها وتنفيذها بواسطة EVM.
يجب التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. ثغرات EVM تشير إلى المشكلات الأمنية الناتجة عن تنفيذ التعليمات في الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي كود إلى الإيثيريوم، سيعمل هذا الكود في نهاية المطاف على كل برنامج عميل P2P للإيثيريوم، وإذا كانت هناك ثغرة أمنية في EVM، فإن ذلك سيؤثر على شبكة الإيثيريوم بالكامل، مما قد يؤدي إلى هجوم حجب الخدمة (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) {
عودة ب ؛
}
}
لم يتم تعديل المتغير storage b، لذلك يجب أن تُرجع دالة run() القيمة الافتراضية 0. ولكن في الواقع، في الكود المُولد من إصدار المترجم الذي يحتوي على ثغرة، ستُرجع الدالة run() القيمة 1.
من الصعب على المطورين العاديين اكتشاف الأخطاء الموجودة في الكود المذكور من خلال مراجعة الكود البسيطة دون فهم ثغرة المترجم. هذا المثال من الكود بسيط نسبيًا، وقد لا يسبب أضرارًا خطيرة بشكل خاص. ولكن إذا تم استخدام المتغير b للتحقق من الأذونات أو محاسبة الأصول، فإن هذا التناقض مع التوقعات قد يؤدي إلى عواقب وخيمة جدًا.
سبب حدوث هذه الظاهرة الشاذة هو أن EVM يستخدم آلة افتراضية قائمة على المكدس، حيث يكون كل عنصر في المكدس بحجم 32 بايت ( أي بحجم متغير uint256 ). من ناحية أخرى، كل فتحة (slot) في التخزين الأساسي (storage) أيضًا بحجم 32 بايت. تدعم لغة Solidity أنواع البيانات المختلفة التي تقل عن 32 بايت مثل uint32، وعندما يتعامل المترجم مع هذه الأنواع من المتغيرات، يحتاج إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا ( clean up ) لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما يحدث تجاوز في الجمع، لم يقم المترجم بشكل صحيح بتنظيف الأجزاء العليا من النتيجة، مما أدى إلى كتابة بت واحد في الأجزاء العليا إلى التخزين، وفي النهاية تغطي المتغير a المتغير b، مما يجعل قيمة المتغير 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 واحدة. في الكود الم مثال أعلاه، توجد كتابة وقراءة في الذاكرة 0 داخل كتلتين assembly مختلفتين، بينما يقوم المترجم فقط بتحليل وتحسين كتلة assembly المنفصلة. نظرًا لأنه لا توجد أي عمليات قراءة بعد كتابة الذاكرة 0 في كتلة assembly الأولى، يتم اعتبار أمر الكتابة هذا زائداً، وبالتالي يتم إزالة هذا الأمر، مما يؤدي إلى حدوث خطأ. في النسخة التي تحتوي على ثغرة، ستعيد الدالة f() القيمة 0، بينما ينبغي أن تعيد الكود أعلاه القيمة الصحيحة 0x42.
تؤثر هذه الثغرة على المترجمين من الإصدار >= 0.5.8 < 0.8.16. اعتبر الكود التالي:
صلابة
العقد C {
وظيفة f(uint8[4] بيانات المكالمات a) العوائد العامة النقية (string memory) {
سلسلة الإرجاع(abi.encode(a));
}
}
في الظروف العادية، يجب أن تكون القيمة العائدة للمتغير a في الكود أعلاه هي "aaaa". لكن في النسخة التي تحتوي على ثغرة، ستعود سلسلة فارغة "".
سبب هذه الثغرة هو أن Solidity قامت بعملية abi.encode لمصفوفات من نوع calldata، وأخطأت في تنظيف بعض البيانات، مما أدى إلى تعديل بيانات أخرى مجاورة، مما تسبب في وجود عدم تناسق في البيانات بعد الترميز وفك الترميز.
من الجدير بالذكر أن Solidity عند إجراء مكالمات خارجية وإصدار أحداث، ستقوم ضمنيًا بترميز المعلمات باستخدام abi.encode، لذا فإن احتمالية ظهور الثغرة المذكورة أعلاه ستكون أعلى مما قد يشعر به المرء بشكل بديهي.
نصائح الأمان
استنادًا إلى تحليل نموذج تهديد ثغرات مترجم Solidity ومراجعة الثغرات التاريخية، نقدم الاقتراحات التالية للمطورين وفرق الأمان.
إلى المطورين:
استخدم إصدارًا أحدث من مترجم Solidity. على الرغم من أن الإصدارات الجديدة قد تُدخل مشكلات أمان جديدة، إلا أن المشكلات الأمنية المعروفة عادة ما تكون أقل من الإصدارات القديمة.
تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم تؤدي إلى عدم تطابق نتائج تنفيذ الكود مع التوقعات. من الصعب اكتشاف هذه المشكلات من خلال مراجعة الكود، لكنها تظهر بسهولة في مرحلة الاختبار. لذلك، من خلال زيادة تغطية الكود، يمكن تقليل حدوث هذه المشكلات إلى الحد الأدنى.
حاول تجنب استخدام التجميع المدمج، والترميز وفك التشفير المعقد لصفوف متعددة الأبعاد والهياكل المعقدة، وتجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى دون الحاجة الواضحة. وفقًا لتحليل الثغرات التاريخية، فإن معظم الثغرات تتعلق بالتجميع المدمج وعمليات الترميز ABI. من الأسهل أن تحدث أخطاء في المترجم عند التعامل مع ميزات اللغة المعقدة. من ناحية أخرى، فإن المطورين قد يقعوا في أخطاء استخدام عند استخدام الميزات الجديدة مما يؤدي إلى مشكلات أمان.
إلى موظفي الأمن:
عند إجراء تدقيق أمني لكود Solidity، لا تتجاهل المخاطر الأمنية التي قد يقدمها مترجم Solidity. في تصنيف ضعف العقود الذكية Weakness Classification(SWC)، العنصر المعني هو SWC-102: إصدار المترجم قديم.
في عملية تطوير SDL الداخلية، يتم حث فريق التطوير على ترقية إصدار مترجم Solidity، ويمكن النظر في إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.
لكن لا داعي للذعر المفرط بشأن ثغرات المترجم، حيث إن معظم ثغرات المترجم تُفعّل فقط في أنماط كود معينة، وليس بالضرورة أن توجد مخاطر أمنية عند استخدام إصدارات مترجم بها ثغرات لتجميع العقود، بل إن التأثير الأمني الفعلي يحتاج إلى تقييم دقيق حسب وضع المشروع.
بعض الموارد المفيدة:
تنبيهات الأمان التي يصدرها فريق Solidity بانتظام:
قائمة الأخطاء التي يتم تحديثها بانتظام في مستودع Solidity الرسمي:
قائمة أخطاء المترجم في الإصدارات المختلفة:
الشيفرة إلى الثغرات الأمنية الموجودة في نسخة المترجم الحالية.
ملخص
تبدأ هذه المقالة بمفاهيم أساسية حول المترجمات، وتقدم ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تنجم عنها في بيئة تطوير Ethereum الفعلية، وفي النهاية تقدم عددًا من النصائح الأمنية العملية للمطورين وموظفي الأمان.
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
تسجيلات الإعجاب 15
أعجبني
15
6
مشاركة
تعليق
0/400
fren.eth
· منذ 1 س
الثغرات هي بمثابة الأبواب الخلفية، لذا لا يجب أن تكون واثقًا جدًا في DeFi.
تفاصيل ثغرات مترجم Solidity واستراتيجيات التخفيف منها
تحليل ثغرات مترجم Solidity واستراتيجيات التعامل معها
المترجم هو أحد المكونات الأساسية لأنظمة الكمبيوتر الحديثة. إنه برنامج كمبيوتر، وتتمثل وظيفته الرئيسية في تحويل شفرة المصدر بلغة البرمجة عالية المستوى، التي يسهل على البشر فهمها وكتابتها، إلى تعليمات قابلة للتنفيذ من قبل وحدة المعالجة المركزية أو آلة افتراضية للبايت.
غالبًا ما يركز معظم المطورين وموظفي الأمان على أمان كود تطبيقات البرامج، لكن قد يتجاهلون أمان المترجم نفسه. في الواقع، المترجم كبرنامج حاسوبي، يحتوي أيضًا على ثغرات أمنية، وقد تؤدي هذه الثغرات في بعض الحالات إلى مخاطر أمنية خطيرة. على سبيل المثال، أثناء عملية تجميع وتحليل وتنفيذ كود جافا سكريبت في المتصفح، قد تؤدي ثغرات في محرك تحليل جافا سكريبت إلى استغلال المهاجمين للثغرات عندما يصل المستخدمون إلى صفحات الويب الضارة، مما يؤدي في النهاية إلى السيطرة على متصفح الضحية أو حتى نظام التشغيل.
لا يُستثنى مترجم Solidity أيضًا، حيث توجد ثغرات أمنية في عدة إصدارات مختلفة.
ثغرات مترجم Solidity
وظيفة مترجم Solidity هي تحويل كود العقد الذكي الذي كتبه المطورون إلى كود تعليمات (EVM) الخاص بـ Ethereum Virtual Machine، حيث يتم تحميل هذه التعليمات EVM عبر معاملات مدمجة على Ethereum، وأخيرًا يتم تحليلها وتنفيذها بواسطة EVM.
يجب التمييز بين ثغرات مترجم Solidity وثغرات EVM نفسها. ثغرات EVM تشير إلى المشكلات الأمنية الناتجة عن تنفيذ التعليمات في الآلة الافتراضية. نظرًا لأن المهاجمين يمكنهم تحميل أي كود إلى الإيثيريوم، سيعمل هذا الكود في نهاية المطاف على كل برنامج عميل P2P للإيثيريوم، وإذا كانت هناك ثغرة أمنية في EVM، فإن ذلك سيؤثر على شبكة الإيثيريوم بالكامل، مما قد يؤدي إلى هجوم حجب الخدمة (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) { عودة ب ؛ } }
لم يتم تعديل المتغير storage b، لذلك يجب أن تُرجع دالة run() القيمة الافتراضية 0. ولكن في الواقع، في الكود المُولد من إصدار المترجم الذي يحتوي على ثغرة، ستُرجع الدالة run() القيمة 1.
من الصعب على المطورين العاديين اكتشاف الأخطاء الموجودة في الكود المذكور من خلال مراجعة الكود البسيطة دون فهم ثغرة المترجم. هذا المثال من الكود بسيط نسبيًا، وقد لا يسبب أضرارًا خطيرة بشكل خاص. ولكن إذا تم استخدام المتغير b للتحقق من الأذونات أو محاسبة الأصول، فإن هذا التناقض مع التوقعات قد يؤدي إلى عواقب وخيمة جدًا.
سبب حدوث هذه الظاهرة الشاذة هو أن EVM يستخدم آلة افتراضية قائمة على المكدس، حيث يكون كل عنصر في المكدس بحجم 32 بايت ( أي بحجم متغير uint256 ). من ناحية أخرى، كل فتحة (slot) في التخزين الأساسي (storage) أيضًا بحجم 32 بايت. تدعم لغة Solidity أنواع البيانات المختلفة التي تقل عن 32 بايت مثل uint32، وعندما يتعامل المترجم مع هذه الأنواع من المتغيرات، يحتاج إلى إجراء عمليات تنظيف مناسبة على الأجزاء العليا ( clean up ) لضمان صحة البيانات. في الحالة المذكورة أعلاه، عندما يحدث تجاوز في الجمع، لم يقم المترجم بشكل صحيح بتنظيف الأجزاء العليا من النتيجة، مما أدى إلى كتابة بت واحد في الأجزاء العليا إلى التخزين، وفي النهاية تغطي المتغير a المتغير b، مما يجعل قيمة المتغير 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 واحدة. في الكود الم مثال أعلاه، توجد كتابة وقراءة في الذاكرة 0 داخل كتلتين assembly مختلفتين، بينما يقوم المترجم فقط بتحليل وتحسين كتلة assembly المنفصلة. نظرًا لأنه لا توجد أي عمليات قراءة بعد كتابة الذاكرة 0 في كتلة assembly الأولى، يتم اعتبار أمر الكتابة هذا زائداً، وبالتالي يتم إزالة هذا الأمر، مما يؤدي إلى حدوث خطأ. في النسخة التي تحتوي على ثغرة، ستعيد الدالة f() القيمة 0، بينما ينبغي أن تعيد الكود أعلاه القيمة الصحيحة 0x42.
SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup
تؤثر هذه الثغرة على المترجمين من الإصدار >= 0.5.8 < 0.8.16. اعتبر الكود التالي:
صلابة العقد C { وظيفة f(uint8[4] بيانات المكالمات a) العوائد العامة النقية (string memory) { سلسلة الإرجاع(abi.encode(a)); } }
في الظروف العادية، يجب أن تكون القيمة العائدة للمتغير a في الكود أعلاه هي "aaaa". لكن في النسخة التي تحتوي على ثغرة، ستعود سلسلة فارغة "".
سبب هذه الثغرة هو أن Solidity قامت بعملية abi.encode لمصفوفات من نوع calldata، وأخطأت في تنظيف بعض البيانات، مما أدى إلى تعديل بيانات أخرى مجاورة، مما تسبب في وجود عدم تناسق في البيانات بعد الترميز وفك الترميز.
من الجدير بالذكر أن Solidity عند إجراء مكالمات خارجية وإصدار أحداث، ستقوم ضمنيًا بترميز المعلمات باستخدام abi.encode، لذا فإن احتمالية ظهور الثغرة المذكورة أعلاه ستكون أعلى مما قد يشعر به المرء بشكل بديهي.
نصائح الأمان
استنادًا إلى تحليل نموذج تهديد ثغرات مترجم Solidity ومراجعة الثغرات التاريخية، نقدم الاقتراحات التالية للمطورين وفرق الأمان.
إلى المطورين:
استخدم إصدارًا أحدث من مترجم Solidity. على الرغم من أن الإصدارات الجديدة قد تُدخل مشكلات أمان جديدة، إلا أن المشكلات الأمنية المعروفة عادة ما تكون أقل من الإصدارات القديمة.
تحسين حالات اختبار الوحدة. معظم الأخطاء على مستوى المترجم تؤدي إلى عدم تطابق نتائج تنفيذ الكود مع التوقعات. من الصعب اكتشاف هذه المشكلات من خلال مراجعة الكود، لكنها تظهر بسهولة في مرحلة الاختبار. لذلك، من خلال زيادة تغطية الكود، يمكن تقليل حدوث هذه المشكلات إلى الحد الأدنى.
حاول تجنب استخدام التجميع المدمج، والترميز وفك التشفير المعقد لصفوف متعددة الأبعاد والهياكل المعقدة، وتجنب استخدام ميزات اللغة الجديدة والوظائف التجريبية بشكل أعمى دون الحاجة الواضحة. وفقًا لتحليل الثغرات التاريخية، فإن معظم الثغرات تتعلق بالتجميع المدمج وعمليات الترميز ABI. من الأسهل أن تحدث أخطاء في المترجم عند التعامل مع ميزات اللغة المعقدة. من ناحية أخرى، فإن المطورين قد يقعوا في أخطاء استخدام عند استخدام الميزات الجديدة مما يؤدي إلى مشكلات أمان.
إلى موظفي الأمن:
عند إجراء تدقيق أمني لكود Solidity، لا تتجاهل المخاطر الأمنية التي قد يقدمها مترجم Solidity. في تصنيف ضعف العقود الذكية Weakness Classification(SWC)، العنصر المعني هو SWC-102: إصدار المترجم قديم.
في عملية تطوير SDL الداخلية، يتم حث فريق التطوير على ترقية إصدار مترجم Solidity، ويمكن النظر في إدخال فحص تلقائي لإصدار المترجم في عملية CI/CD.
لكن لا داعي للذعر المفرط بشأن ثغرات المترجم، حيث إن معظم ثغرات المترجم تُفعّل فقط في أنماط كود معينة، وليس بالضرورة أن توجد مخاطر أمنية عند استخدام إصدارات مترجم بها ثغرات لتجميع العقود، بل إن التأثير الأمني الفعلي يحتاج إلى تقييم دقيق حسب وضع المشروع.
بعض الموارد المفيدة:
تنبيهات الأمان التي يصدرها فريق Solidity بانتظام:
قائمة الأخطاء التي يتم تحديثها بانتظام في مستودع Solidity الرسمي:
قائمة أخطاء المترجم في الإصدارات المختلفة:
الشيفرة إلى الثغرات الأمنية الموجودة في نسخة المترجم الحالية.
ملخص
تبدأ هذه المقالة بمفاهيم أساسية حول المترجمات، وتقدم ثغرات مترجم Solidity، وتحلل المخاطر الأمنية التي قد تنجم عنها في بيئة تطوير Ethereum الفعلية، وفي النهاية تقدم عددًا من النصائح الأمنية العملية للمطورين وموظفي الأمان.