لأغراض تعليمية فقط؛ وليس نصيحة استثمارية. قد تؤدي ثغرة إعادة الدخول إلى خسارة سريعة وغير قابلة للعكس لأصول العقد، ولا يثبت أي دفاع أو تدقيق منفرد أن العقد آمن.
الإجابة المباشرة
قد يقع هجوم إعادة الدخول عندما يستدعي منطق العقد جهة خارجية فتعاود الجهة المستدعاة الاتصال قبل اكتمال التنفيذ الأصلي واستعادة ثوابته. إذا بقيت أرصدة أو حصص أو صلاحيات أو أسعار قديمة ظاهرة، فقد يكرر callback إجراءً أو يؤثر في إجراء آخر باستخدام حالة غير متسقة.
لا يلزم أن يدخل callback إلى الدالة نفسها أو أن ينقل العملة الأصلية. فقد تنقل hooks الرموز وcallbacks مستلمي NFT واستدعاءات الخزائن أو الاستراتيجيات وcallbacks القروض السريعة التحكم إلى كود غير موثوق. ويمكن أن تعبر إعادة الدخول الدوال والعقود والوحدات، كما قد تجعل إعادة الدخول للقراءة فقط بروتوكولاً آخر يستهلك قيمة مؤقتة.
آلية العمل
يسير الاستغلال المعتاد وفق التسلسل الآتي:
- يدخل المهاجم دالة تغير الحالة ويجتاز فحوصها الأولية.
- يستدعي العقد الضعيف عنواناً أو رمزاً أو بروتوكولاً قبل إكمال محاسبته.
- يدخل كود يتحكم فيه المهاجم إلى العقد الأصلي أو عقد متصل بينما تظل الحالة القديمة ظاهرة.
- يكرر الاستدعاء المتداخل تأثيراً أو يغير حالة مشتركة، ثم يعود التنفيذ بعد كسر أحد الثوابت.
قد يكون نقل التحكم الخارجي صريحاً، مثل الاستدعاء منخفض المستوى، أو مخفياً خلف نقل رمز أو hook للمستلم أو mint آمن أو محول استراتيجية أو واجهة استدعاء عشوائي. يعيد revert عادةً شجرة الاستدعاءات المتأثرة، لكن المهاجم قد يرتب سلسلة متداخلة ناجحة تعود طبيعياً بعد استخراج قيمة أو إفساد المحاسبة.
يجب تطبيق وسائل حماية متعددة:
- اتباع نمط الفحوص-التأثيرات-التفاعلات: التحقق أولاً، ثم تثبيت كل التأثيرات الداخلية ذات الصلة، ثم التفاعل الخارجي أخيراً.
- استخدام حارس على كل نقطة دخول تشترك في الثابت المحمي، لا على الدالة ذات الاستدعاء الواضح فقط.
- تفضيل المطالبات التي يبدأها المستفيد عند ملاءمتها وتقليل استدعاءات الرموز والمستلمين وhooks والوكلاء والتكاملات غير الموثوقة.
- تعريف ثوابت بين العقود واختبار callbacks الخبيثة والمسارات بين الدوال وmulticalls المتداخلة والمستهلكين للقراءة فقط.
- دمج مراجعة التنفيذ مع المراقبة والإيقاف المؤقت والاستجابة للحوادث عندما يسمح التصميم.
مثال
لنفترض خزينة ترسل القيمة ولا تصفر رصيد المستخدم إلا بعد الاستدعاء:
function withdraw() external {
uint256 amount = balances[msg.sender];
require(amount > 0, "empty balance");
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "transfer failed");
balances[msg.sender] = 0;
}يحصل المستلم على التحكم بينما لا يزال balances[msg.sender] يحمل المبلغ القديم. ويمكن لدالة الاستلام أن تستدعي withdraw() مجدداً وتجتاز الفحص نفسه وتطلب تحويلاً آخر. يؤدي تحديث الرصيد قبل الاستدعاء إلى إغلاق هذه النافذة، ويمكن للحارس رفض الدخول المتداخل. لكن أياً منهما لا يثبت أمان النظام كله، لأن نقطة دخول أخرى أو عقداً متصلاً قد يكشف الثابت غير المكتمل نفسه.
المخاطر
- يحمي الحارس دالة واحدة بينما تكشف دالة أخرى الحالة نفسها.
- يكون ترتيب الاستدعاء المحلي صحيحاً لكن ثابتاً بين العقود يظل غير متسق أثناء callback.
- ينفذ رمز أو مستلم أو callback قرض سريع أو محول استراتيجية كوداً خارجياً على نحو غير متوقع.
- تنشر دالة view سعراً أو معدل تحويل مؤقتاً يستخدمه بروتوكول آخر في المعاملة نفسها.
- يتجاوز تحديث أو وحدة أو تغيير في تخطيط التخزين القفل الأصلي أو يفسده.
- تغطي الاختبارات السحب العودي لكنها تهمل المسارات بين الدوال والعقود ومسارات القراءة فقط.
بالنسبة للمستخدم، تشير شارة التدقيق أو حارس إعادة الدخول إلى وجود وسيلة تحكم، وليست ضماناً. قد تغير الترقيات والتكاملات وإجراءات الطوارئ ذات الامتياز سطح الهجوم. قلل الموافقات والتعرض، وتحقق من التنفيذ المنشور، ولا تفترض إمكانية عكس الخسائر.
مفاهيم خاطئة شائعة
- إعادة الدخول تعني فقط تكرار دالة سحب واحدة. قد تدخل دالة أو عقداً آخر، أو تعرض بيانات غير متسقة لقارئ.
- تحويلات العملة الأصلية وحدها تشغل callbacks. يمكن لمعايير الرموز وhooks المستلمين والتكاملات تشغيل كود خارجي أيضاً.
- الحارس أو نمط الفحوص-التأثيرات-التفاعلات يجعل العقد آمناً. لا يزال نطاقه وكل نقاط الدخول المشتركة والثوابت بين العقود بحاجة إلى مراجعة.
- التدقيق الناجح يستبعد إعادة الدخول. نطاق التدقيق محدود؛ وقد تنشئ التغييرات اللاحقة والتكاملات غير المراجعة مسارات جديدة.
موضوعات ذات صلة
المصادر
- اعتبارات الأمان - Solidity Documentation (تاريخ الاطلاع: 2026-08-21)
- أمان العقود الذكية - ethereum.org (تاريخ الاطلاع: 2026-08-21)
- ReentrancyGuard - OpenZeppelin Documentation (تاريخ الاطلاع: 2026-08-21)
- SC08:2026 هجمات إعادة الدخول - OWASP Smart Contract Security (تاريخ الاطلاع: 2026-08-21)