والهجمات الضارية كثيرة فهجوم ال SQL Injection أو حقن الاستعلام هي أحد تلك الهجمات وتعتبر من أشد الأخطار التي يمكنها أن تدمر ما برمجته من موقع أو برنامج ، فيمكن للمخترق أن يقوم بمسح قاعدة البيانات كاملة أو جزء منها أو سرقة محتوياتها أو التعديل عليها وذلك بتعديل بسيط في نماذج الإدخال أو بتغيير بسيط جدا في عنوان الموقع.
فهذا النوع من الهجمات يعتمد على إضافة جملة استعلام إلى المتغيرات الممررة للنظام بحيث يتم تنفيذ هذه الإضافة كجزء من جملة الاستعلام الأساسية الموجودة في النظام.
فعلى سبيل المثال لو قمت بكتابة الأمر التالي في موقعك:-
String str="Select count(*) from users where username=' " + txtuser.Text + " ' and password=' " + txtpassword.Text + " ' "; Int x; SqlCommand cmd=new SqlCommand(str,con); X=(int) cmd.ExecuteScalar(); If (x>0){ FormsAuthentication.RedirectFromloginPage(txtuser.Text,false); } else{ lblMsg.Text="Login attempt failed"; } Con.Close();
في هذا المثال يوجد إمكانية للمخترق بإدخال النص التالي في صندوق النص الخاص باسم المستخدم ليستطيع الدخول إلى النظام بدون الحاجة إلى اسم مستخدم وكلمة مرور وذلك بإضافة أحرف بسيطة مثل
Select count(*) from users where username = ' ' or 1=1 --
أترى خطورة الأمر…أنت الآن قدمت موقعك للمخترق على طبق من ذهب
رغم خطورة هذا الأمر ، إلا أن الحل لا يحتاج إلى جهد كبير أو خبرة عالية.
لأن الحل أسهل مما تتوقع ، فالأسلوب البرمجي بحد ذاته يعتبر عامل أساسي في تحديد مستوى الأمان الذي يتحلى به الموقع
فلحماية موقعك من هجوم ال SQL Injection، يتطلب منك فقط تحسين أسلوبك البرمجي بإتباع التالي:
• لا تثق أبدا بما يدخله المستخدم من قيم في موقعك فيجب عليك التحقق من القيم المدخلة بواسطة أدوات التحقق وأيضا تقليل طول المدخلات التي يدخلها المستخدم فإذا كانت كلمة السر طولها 10 أحرف فيجب عدم السماح للمستخدم بتعدي الطول المسموح وذلك من خلال الخاصية maxlength
• لا تستخدم أبدا طريقة تمرير قيم المستخدم مباشرة في جملة الاستعلام كما في المثال الذي طرحته سابقا، ولكن يجب عليك استخدام الوسيطات ( SQL Parameters) أو الإجراءات المخزنة (Stored Procedures)
ولنكتب المثال السابق بطريقة آمنة ولكن لا تنسى قبل استخدام الوسيطات التحقق من القيم الممررة:
String str="Select count(*) from users where username=@username and password= @password"; cmd.Parameters.AddWithValue("@username", txtuser.Text); cmd.Parameters.AddWithValue("@password", txtpassword.Text); Int x; SqlCommand cmd=new SqlCommand(str,con); X=(int) cmd.ExecuteScalar(); If (x>0){ FormsAuthentication.RedirectFromloginPage(txtuser.Text,false); } else{ lblMsg.Text="Login attempt failed"; } Con.Close();
CREATE PROCEDURE sp_getUser @username varchar(200) = NULL AS DECLARE @sql nvarchar(4000) SELECT @sql = ' SELECT [name], [address] ' + ' FROM [USERS] Where [username] = "' + @username + "" EXEC (@sql)
فالمشكلة تكمن في أن الوسيط بدلا من أن يكون هو النص المستخدم للبحث من خلاله في الاستعلام سيكون جزء من الاستعلام نفسه
ولجعل هذا الإجراء أكثر أمنا بالشكل التالي:
CREATE PROCEDURE sp_getUser @username varchar(200) = NULL AS DECLARE @sql nvarchar(4000) SELECT @sql = ' SELECT [name], [address] ' + ' FROM [USERS] Where [username] = ' SELECT @sql = @sql + ' [username] LIKE @username' EXEC sp_executesql @sql, N'@username varchar(200)', @username
• لا تخزن معلومات حساسة في ملفات واضحة بل قم بتشفير كلمات السر وجميع البيانات الحساسة وأيضا يجب تشفير جملة الاتصال إذا كانت تحتوي على كلمة سر
• لا تقم بوضع تفاصيل كثيرة في رسائل الخطأ، فالكثير من المبرمجين يقومون بتوضيح مكان المشكلة في الاستعلام وفي أي جدول في قاعدة البيانات وهذه التفاصيل تمكن المخترق من تكوين صورة كاملة عن بنية قاعدة البيانات الخاصة بالنظام حتى وإن لم يرى الشيفرة المصدرية.
الآن وبعد توضيح طريقة هجوم ال SQL Injection وإعطاءك الحلول اللازمة لتفادي هذا الهجوم والحفاظ على موقعك بشكل آمن
اتضح لديك الطريقة الأمثل لرفع مستوى الأمان لموقعك، فيجب عليك أيها المطور أن تقوم بتحسين كودك البرمجي بدلا من أن تقوم بتضييع وقتك الثمين للبحث عن أفضل طرق الأمان وهي موجودة بين يديك.