منشور

سلسلة دروس SQL| injection

هذه المقالة جزء من سلسلة دروس SQL، يمكنك الاطلاع على الفهرس

حقن SQL

حقن SQL هو تقنية إدخال التعليمات البرمجية التي قد تدمر قاعدة البيانات الخاصة بك.

يعد حقن SQL أحد أكثر تقنيات اختراق الويب شيوعًا.

حقن SQL هو وضع التعليمات البرمجية الضارة في عبارات SQL، عبر إدخال صفحة الويب.

SQL في صفحات الويب

عادة ما يحدث حقن SQL عندما تطلب من المستخدم إدخال مثل اسم المستخدم / معرف المستخدم الخاص به، وبدلاً من الاسم / المعرف، يمنحك المستخدم عبارة SQL التي ستقوم بتشغيلها دون علم على قاعدة البيانات الخاصة بك.

انظر إلى المثال التالي الذي ينشئ عبارة SELECT عن طريق إضافة متغير (txtUserId) إلى سلسلة تحديد. يتم جلب المتغير من إدخال المستخدم (getRequestString):

مثال

1
2
3
4
5
		txtUserId = getRequestString("UserId");

		txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

يصف الجزء المتبقي من هذا الفصل المخاطر المحتملة لاستخدام إدخال المستخدم في عبارات SQL.

حقن SQL على أساس 1 = 1 صحيح دائمًا

انظر إلى المثال أعلاه مرة أخرى. كان الغرض الأصلي من التعليمات البرمجية إنشاء عبارة SQL لتحديد مستخدم بمعرف مستخدم معين.

إذا لم يكن هناك شيء يمنع المستخدم من إدخال الإدخال “الخاطئ” ، فيمكن للمستخدم إدخال الإدخال “الذكي” مثل هذا:

UserId: 105 OR 1=1

بعد ذلك ، ستبدو عبارة SQL كما يلي:

1
2
3
		SELECT * FROM Users WHERE UserId = 105 OR 1=1;

SQL أعلاه صالحة وستُرجع جميع الصفوف من جدول “المستخدمون” ، حيث أن OR 1 = 1 دائمًا TRUE.

هل يبدو المثال أعلاه خطيرًا؟ ماذا لو احتوى جدول “المستخدمون” على أسماء وكلمات مرور؟

عبارة SQL أعلاه هي نفسها تقريبًا:

1
2
3
		SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1; 

قد يتمكن المخترق من الوصول إلى جميع أسماء المستخدمين وكلمات المرور في قاعدة البيانات ، بمجرد إدخال 105 OR 1 = 1 في حقل الإدخال.

حقن SQL على أساس “” = “” صحيح دائمًا

فيما يلي مثال لتسجيل دخول المستخدم على موقع ويب:

اسم المستخدم:

فلان الفلاني “John Doe”

كلمه السر:

كلمة المرور الخاصة بي “myPass”

مثال

1
2
3
4
5
6
7
		uName = getRequestString("username");

		uPass = getRequestString("userpassword");

		sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

النتيجة

1
2
3
 SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass" 

قد يتمكن المخترق من الوصول إلى أسماء المستخدمين وكلمات المرور في قاعدة بيانات بمجرد إدخال “OR” “=” في مربع نص اسم المستخدم أو كلمة المرور:

اسم المستخدم:

” or “”=”

كلمه السر:

” or “”=”

سيقوم الكود الموجود على الخادم بإنشاء جملة SQL صالحة مثل هذا:

النتيجة

1
2
3
		 SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""="" 

إن SQL أعلاه صالحة وستُرجع جميع الصفوف من جدول “Users” ، نظرًا لأن OR “” = “” هي دائمًا TRUE.

حقن SQL استناداً إلى عدة عبارات SQL مجتمعة

تدعم معظم قواعد البيانات جملة SQL المجمعة.

مجموعة عبارات SQL هي مجموعة من عبارات SQL أو أكثر، مفصولة بفواصل منقوطة.

ستقوم عبارة SQL أدناه بإرجاع كافة الصفوف من جدول “المستخدمون”، ثم حذف جدول “الموردين”.

مثال

1
2
3
4

		SELECT * FROM Users; DROP TABLE Suppliers 

فلننظر إلى المثال التالي:

مثال

1
2
3
4
5
		txtUserId = getRequestString("UserId");

		txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

والمدخلات التالية:

معرف المستخدم : 105; DROP TABLE Suppliers “حذف جدول الموردين”

ستبدو عبارة SQL الصالحة كما يلي:

النتيجة

1
2
3
		SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers

استخدم معلمات SQL للحماية

لحماية موقع ويب من حقن SQL ، يمكنك استخدام معلمات SQL.

معلمات SQL هي القيم التي تتم إضافتها إلى استعلام SQL في وقت التنفيذ، بطريقة يتم التحكم فيها.

مثال ASP.NET Razor

1
2
3
4
5
6
7
		txtUserId = getRequestString("UserId");

		txtSQL = "SELECT * FROM Users WHERE UserId = @0";

		db.Execute(txtSQL,txtUserId);

لاحظ أن المعلمات ممثلة في جملة SQL بعلامة @.

يتحقق مشغل SQL من كل معلمة للتأكد من أنها صحيحة لعمودها ويتم التعامل معها بشكل حرفي ، وليس كجزء من SQL ليتم تنفيذها.

مثال آخر

1
2
3
4
5
6
7
8
9
10
11
		txtNam = getRequestString("CustomerName");

		txtAdd = getRequestString("Address");

		txtCit = getRequestString("City");

		txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";

		db.Execute(txtSQL,txtNam,txtAdd,txtCit);

أمثلة

توضح الأمثلة التالية كيفية إنشاء استعلامات ذات معلمات في بعض لغات الويب الشائعة.

عبارة SELECT في ASP.NET:

1
2
3
4
5
6
7
8
9
10
11
		 txtUserId = getRequestString("UserId");

		sql = "SELECT * FROM Customers WHERE CustomerId = @0";

		command = new SqlCommand(sql);

		command.Parameters.AddWithValue("@0",txtUserID);

		command.ExecuteReader();

عبارة INSERT INTO في IN ASP.NET:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
		txtNam = getRequestString("CustomerName");

		txtAdd = getRequestString("Address");

		txtCit = getRequestString("City");

		txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";

		command = new SqlCommand(txtSQL);

		command.Parameters.AddWithValue("@0",txtNam);

		command.Parameters.AddWithValue("@1",txtAdd);

		command.Parameters.AddWithValue("@2",txtCit);

		command.ExecuteNonQuery();

عبارة INSERT INTO في PHP:

1
2
3
4
5
6
7
8
9
10
11
12
13
		$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)

		VALUES (:nam, :add, :cit)");

		$stmt->bindParam(':nam', $txtNam);

		$stmt->bindParam(':add', $txtAdd);

		$stmt->bindParam(':cit', $txtCit);

		$stmt->execute();

هذا المنشور تحت ترخيص CC BY 4.0 بواسطة المؤلف.