04/06/2026
ليه الـ Firewalls وأدوات الـ Scanners التلقائية مش هتحميك لو عندك ثغرة Race Condition في الـ Backend بتاعك؟ 💣
(قصة ثغرة برمجية ممكن تكلّف أي شركة FinTech ملايين في ثواني!) 👇
تخيل معايا إن عندنا تطبيق بنكي (أو محفظة إلكترونية)، يوزر عنده في رصيده 100 جنيه بس، وعايز يسحبهم.
الـ Logic الطبيعي اللي أي مبرمج بيكتبه بيكون كالتالي:
1️⃣ السيرفر بيشيك (Check): هل رصيد اليوزر أكبر من أو يساوي 100؟
2️⃣ لو الإجابة أيوة، بيطلع فلوس للمستخدم.
3️⃣ السيرفر بيحدث الداتابيز (Update) ويخصم الـ 100 جنيه، ويبقى الرصيد صفر.
الكود ده شغال ومفيهوش أي Error.. صح؟
خطأ كارثي! 🚨
هنا بيجي دور الـ Attacker. لو الهكر استخدم أداة زي (Burp Suite Intruder) وبعت 10 طلبات سحب (Requests) في نفس الميكرو-ثانية!
اللي بيحصل في السيرفر هو الـ "Race Condition" (حالة سباق):
السيرفر بيستقبل الـ 10 طلبات مع بعض في نفس اللحظة.. بيدخلهم على خطوة رقم (1).. بيلاقي الرصيد 100 جنيه (لأن مفيش ولا طلب لحق يوصل لخطوة 3 ويخصم الرصيد لسه!).
النتيجة؟ السيرفر بيوافق على الـ 10 عمليات، والهكر بيسحب 1000 جنيه وهو أصلاً معندوش غير 100! 🤯💸
🛠️ إزاي نقفل الثغرة دي هندسياً؟ (The Fix)
المشكلة دي حلها مش في الـ Security Tools، حلها في الـ Architecture والداتابيز:
✔️ الحل الأول (Pessimistic Locking):
استخدام الـ Transactions مع (SELECT ... FOR UPDATE). الفكرة هنا إن أول Request يدخل، بيعمل "قفل" (Lock) على الصف (Row) الخاص باليوزر في الداتابيز. أي طلبات تانية بتفضل "واقفة مستنية" لحد ما الطلب الأول يخلص تماماً ويخصم الرصيد.
✔️ الحل الثاني (Database Constraints):
إننا نحط شرط صارم في الداتابيز نفسها إن خانة الرصيد مستحيل تنزل تحت الصفر: CHECK (balance >= 0). وقتها الداتابيز هترفض أي عملية تخلي الرصيد بالسالب.
الـ Business Logic Vulnerabilities هي الكابوس الحقيقي لأي سيستم لأن مفيش أداة بتكتشفها أوتوماتيك بسهولة.
قولي يا هندسة: إيه الطريقة المفضلة ليك لقفل ثغرات الـ Concurrency؟ هل بتعتمد على الـ Database Locks، ولا بتفضل تستخدم Distributed Locks عن طريق Redis؟ شاركنا رأيك في الكومنتات! 👇💬
#برمجة