1. ما هو هجوم حقن SQL؟
ويعني ما يسمى بهجوم حقن SQL أن المهاجم يقوم بإدخال أوامر SQL في حقل الإدخال الخاص بنموذج ويب أو سلسلة الاستعلام لطلب صفحة، ويخدع الخادم لتنفيذ أوامر SQL ضارة. في بعض النماذج، يتم استخدام إدخال المستخدم مباشرة لإنشاء (أو التأثير) على أوامر SQL الديناميكية، أو كمعلمات إدخال للإجراءات المخزنة، وتكون هذه النماذج عرضة بشكل خاص لهجمات حقن SQL. تتضمن عمليات هجوم حقن SQL الشائعة ما يلي:
⑴ يحتوي تطبيق ويب ASP.NET على صفحة تسجيل دخول تتحكم في ما إذا كان لدى المستخدم الحق في الوصول إلى التطبيق، وتتطلب من المستخدم إدخال اسم وكلمة مرور.
⑵ سيتم استخدام المحتوى الذي تم إدخاله في صفحة تسجيل الدخول مباشرة لإنشاء أوامر SQL ديناميكية، أو سيتم استخدامه مباشرة كمعلمات للإجراءات المخزنة. فيما يلي مثال لتطبيق ASP.NET يقوم بإنشاء استعلام:
System.Text.StringBuilder query = new System.Text.StringBuilder(
"اختر * من المستخدمين حيث تسجيل الدخول = '")
.Append(txtLogin.Text).Append("' وكلمة المرور ='")
.Append(txtPassword.Text).Append("'");
⑶ يقوم المهاجم بإدخال شيء مثل "" أو '1'='1" في مربعات إدخال اسم المستخدم وكلمة المرور.
⑷ بعد إرسال المحتوى الذي أدخله المستخدم إلى الخادم، يقوم الخادم بتشغيل رمز ASP.NET أعلاه لإنشاء أمر SQL للاستعلام عن المستخدم. ومع ذلك، نظرًا لأن إدخال المحتوى بواسطة المهاجم خاص جدًا، فإن أمر SQL النهائي يصبح: SELECT * من المستخدمين حيث تسجيل الدخول = '' أو '1'='1' وكلمة المرور = '' أو '1'='1'.
⑸ ينفذ الخادم استعلامًا أو عملية مخزنة لمقارنة معلومات الهوية التي أدخلها المستخدم مع معلومات الهوية المحفوظة في الخادم.
⑹ نظرًا لأن أمر SQL قد تم تعديله بالفعل من خلال هجوم الحقن ولا يمكنه التحقق من هوية المستخدم حقًا، فسيقوم النظام بتفويض المهاجم بشكل غير صحيح.
إذا علم المهاجم أن التطبيق سيستخدم المحتوى المُدخل في النموذج مباشرة لاستعلامات التحقق من الهوية، فسيحاول إدخال بعض سلاسل SQL الخاصة للتلاعب بالاستعلام لتغيير وظيفته الأصلية وخداع النظام لمنح أذونات الوصول.
اعتمادًا على بيئة النظام، يختلف الضرر الذي قد يسببه المهاجم أيضًا، والذي يتم تحديده بشكل أساسي من خلال الأذونات الأمنية للتطبيق للوصول إلى قاعدة البيانات. إذا كان حساب المستخدم يتمتع بحقوق إدارية أو غيرها من الحقوق المتقدمة نسبيًا، فقد يقوم المهاجم بتنفيذ عمليات مختلفة على جداول قاعدة البيانات التي يريد القيام بها، بما في ذلك إضافة البيانات أو حذفها أو تحديثها، أو حتى حذف الجدول مباشرة.
2. كيفية الوقاية؟
لحسن الحظ، ليس من الصعب بشكل خاص منع اختراق تطبيقات ASP.NET بواسطة هجمات حقن SQL. كل ما عليك فعله هو تصفية كل محتوى الإدخال قبل استخدام محتوى إدخال النموذج لإنشاء أمر SQL. يمكن إجراء تصفية المدخلات بعدة طرق.
⑴ بالنسبة للمواقف التي يتم فيها إنشاء استعلامات SQL ديناميكيًا، يمكن استخدام التقنيات التالية:
أولاً: استبدال علامات الاقتباس المفردة، أي تغيير جميع علامات الاقتباس المفردة إلى علامتي اقتباس مفردتين لمنع المهاجمين من تعديل معنى أوامر SQL. بالنظر إلى المثال السابق مرة أخرى، من الواضح أن "SELECT * from Users WHERE تسجيل الدخول = ''' أو ''1''=''1' AND كلمة المرور = ''' أو ''1''=''1'" ستحصل عليه بوضوح نفس النتائج "SELECT * from Users WHERE تسجيل الدخول = '' أو '1'='1' وكلمة المرور = '' أو '1'='1'" مختلفة.
ثانيًا: إزالة جميع الواصلات في محتوى إدخال المستخدم لمنع المهاجمين من إنشاء استعلامات مثل "SELECT * from Users WHERElogin = 'mas' -- ANDpassword =''"، لأن لاحقة مثل هذه الاستعلامات تم التعليق على نصفها خارج ولم يعد صالحًا، يحتاج المهاجم فقط إلى معرفة اسم تسجيل دخول مستخدم قانوني ولا يحتاج إلى معرفة كلمة مرور المستخدم للوصول بنجاح.
ثالثاً: تحديد صلاحيات حساب قاعدة البيانات المستخدم لتنفيذ الاستعلامات. استخدم حسابات مستخدمين مختلفة لإجراء عمليات الاستعلام والإدراج والتحديث والحذف. من خلال عزل العمليات التي يمكن إجراؤها بواسطة حسابات مختلفة، فإنه يمنع استخدام المكان المستخدم أصلاً لتنفيذ أمر SELECT لتنفيذ أمر INSERT أو UPDATE أو DELETE.
⑵ استخدم الإجراءات المخزنة لتنفيذ جميع الاستعلامات. ستمنع الطريقة التي يتم بها تمرير معلمات SQL المهاجمين من استخدام علامات الاقتباس والواصلات المفردة لتنفيذ الهجمات. بالإضافة إلى ذلك، فإنه يسمح أيضًا بتقييد أذونات قاعدة البيانات للسماح فقط بتنفيذ إجراءات مخزنة محددة. يجب أن تتوافق جميع مدخلات المستخدم مع السياق الأمني للإجراء المخزن المسمى، بحيث يكون من الصعب حدوث هجمات الحقن.
⑶ تحديد طول النموذج أو إدخال سلسلة الاستعلام. إذا كان اسم تسجيل الدخول الخاص بالمستخدم يتكون من 10 أحرف كحد أقصى، فلا تقبل أكثر من 10 أحرف تم إدخالها في النموذج، وسيؤدي ذلك إلى زيادة صعوبة قيام المهاجمين بإدراج تعليمات برمجية ضارة في أوامر SQL.
⑷ تحقق من شرعية إدخال المستخدم وتأكد من أن محتوى الإدخال يحتوي فقط على بيانات قانونية. يجب إجراء فحص البيانات على جانبي العميل والخادم - يتم إجراء التحقق من جانب الخادم للتعويض عن الأمان الهش لآلية التحقق من جانب العميل.
من جانب العميل، من الممكن تمامًا للمهاجم الحصول على الكود المصدري لصفحة الويب، وتعديل البرنامج النصي الذي يتحقق من الشرعية (أو حذف البرنامج النصي مباشرة)، ثم إرسال المحتوى غير القانوني إلى الخادم من خلال النموذج المعدل. ولذلك، فإن الطريقة الوحيدة للتأكد من أن عملية التحقق قد تم تنفيذها بالفعل هي إجراء التحقق من جانب الخادم أيضًا. يمكنك استخدام العديد من كائنات التحقق المضمنة، مثل RegularExpressionValidator، والتي يمكنها إنشاء برامج نصية من جانب العميل تلقائيًا للتحقق من الصحة، وبالطبع يمكنك أيضًا إدراج استدعاءات الأساليب من جانب الخادم. إذا لم تتمكن من العثور على كائن التحقق الجاهز، فيمكنك إنشاء واحد بنفسك من خلال CustomValidator.
⑸ تشفير وحفظ اسم تسجيل دخول المستخدم وكلمة المرور والبيانات الأخرى. إن تشفير البيانات التي يدخلها المستخدم ومن ثم مقارنتها بالبيانات المحفوظة في قاعدة البيانات يعادل "تعقيم" البيانات التي يدخلها المستخدم، ولم تعد البيانات التي يدخلها المستخدم لها أي معنى خاص لقاعدة البيانات، لذا فهي تمنع المهاجمين من حقن أوامر SQL. تحتوي فئة System.Web.Security.FormsAuthentication على ملف HashPasswordForStoringInConfigFile، وهو مناسب جدًا لتطهير بيانات الإدخال.
⑹ تحقق من عدد السجلات التي أرجعها الاستعلام الذي استخرج البيانات. إذا كان البرنامج يتطلب إرجاع سجل واحد فقط، ولكن السجل الفعلي الذي تم إرجاعه يحتوي على أكثر من صف واحد، فسيتم التعامل معه على أنه خطأ.