حقن قواعد البيانات (SQL Injection)
كيف يتحول نص تكتبه في نموذج إلى أمر داخل قاعدة البيانات ولماذا يحدث وكيف يمنع نهائيا
- المسار
- أمن الويب
- الوقت المتوقع
- 30 د
- المستوى
- مبتدئ
قبل هذا الدرس
تخزن أغلب المواقع بياناتها في قاعدة بيانات (database) وتتحدث معها بلغة اسمها SQL. حين يكتب التطبيق أوامر SQL بلصق ما أدخلته أنت داخلها مباشرة يصبح بإمكانك أن تكتب ليس بيانات بل أوامر هذه هي ثغرة حقن قواعد البيانات (SQL Injection).
ما هي الثغرة؟
لنأخذ نموذج تسجيل دخول التطبيق يريد أن يسأل قاعدة البيانات: هل يوجد مستخدم بهذا الاسم وكلمة المرور؟ فيبني الأمر التالي بلصق ما كتبته:
const sql = "SELECT * FROM users WHERE username = '" + username +
"' AND password = '" + password + "'";لو كتبت اسم المستخدم sara وكلمة المرور 1234 يصبح الأمر:
SELECT * FROM users WHERE username = 'sara' AND password = '1234'المشكلة أن علامة ' التي تحيط بالنص في SQL. ما بين علامتين منها يعامل كنص وما خارجهما يعامل كأوامر. التي تفصل النص عن الأوامر يستطيع المستخدم أن يكتبها بنفسه
لماذا تحدث؟
تحدث لأن التطبيق خلط شيئين مختلفين في مكان واحد: الأوامر التي كتبها المبرمج والبيانات التي أدخلها المستخدم قاعدة البيانات تستقبل نصا واحدا ولا تعرف أي جزء منه جاء من المبرمج وأيه جاء من المستخدم فتنفذ الكل
مثال كود مصاب
إذا كتبت في خانة اسم المستخدم هذا النص:
admin'--يصبح الأمر الذي تنفذه قاعدة البيانات:
SELECT * FROM users WHERE username = 'admin'-- ' AND password = '...'علامة الاقتباس أغلقت الاسم بعد admin والرمز -- في SQL يعني “تجاهل بقية السطر” فاختفى فحص كلمة المرور تماما النتيجة: دخلت بحساب المدير دون أن تعرف كلمة مروره
أثرها في الواقع
حقن قواعد البيانات من أخطر ثغرات الويب وأكثرها شهرة وما زالت تظهر حتى اليوم حسب ما يرصده المهتمون بأمن الويب يمكن أن تقود إلى:
- تجاوز تسجيل الدخول والدخول كأي مستخدم
- قراءة بيانات لا تخصك: بيانات المستخدمين كلمات المرور المخزنة معلومات داخلية
- في الحالات الأسوأ تعديل البيانات أو حذفها
كيف تطبق بنفسك
هذا الدرس له ثلاثة لابات بالترتيب كل واحد أصعب من الذي قبله:
- تجاوز تسجيل الدخول (سهل): لا حماية والصفحة تعرض لك الأمر المنفذ
- تجاوز فلتر كلمات (متوسط): فيه “حماية” ناقصة وستفهم لماذا لا تكفي
- حقن أعمى (صعب): لا تظهر أي بيانات وتستخرج السر بسؤال نعم/لا متكرر
جربها في قسم اللابات بالأسفل المستوى التالي يفتح بعد حل الذي قبله
كيف تمنع
الإصلاح الصحيح والوحيد هو الاستعلامات ذات المعاملات (parameterized queries أو prepared statements): نكتب نص الأمر ثابتا مع أماكن فارغة ونمرر القيم منفصلة عنه
// نص الأمر ثابت، والقيم تمرّر منفصلة كبيانات لا تتحول أبدا إلى أوامر.
const user = db.get(
'SELECT id, role FROM users WHERE username = ? AND password_hash = ?',
[username, hash]
);بهذه الطريقة مهما كتبت في الخانة من علامات اقتباس أو كلمات SQL تبقى مجرد قيمة نصية تقارن ولا تستطيع أن تصبح جزءا من الأمر
اللابات
تجاوز تسجيل الدخول
محلولسهللاب في المتصفح
ادخل بحساب المدير admin دون أن تعرف كلمة مروره
ادخل اللابمقفلتجاوز فلتر كلمات
محلولمتوسطلاب في المتصفح
استخرج رمز القسيمة من جدول الملاحظات ثم أدخله في خانة القسيمة
ادخل اللابمقفلحقن أعمى
محلولصعبلاب في المتصفح
استخرج رمز إعادة التعيين الخاص بالمدير كاملا ثم أدخله
ادخل اللابمقفل
