في ورقة الغش هذه ، سنفترض ما يلي:
- أنت مطور أو تعرف البرمجة
- لديك معرفة محدودة بأمان تطبيق الويب
- أنت بحاجة إلى معرفة كيفية حدوث هجمات حقن SQL
- تحتاج إلى معرفة كيفية إصلاح مشكلات حقن SQL في التعليمات البرمجية الخاصة بك
ستتعلم في ورقة الغش هذه:
- كيف يقوم المتسللون الخبثاء بتنفيذ هجمات حقن SQL
- كيفية إصلاح التعليمات البرمجية التي بها ثغرات أمنية في حقن SQL
- كيفية تجنب الثغرات الأمنية حقن SQL للمستقبل
المحتويات
1. هجمات حقن SQL
1.1. معلومات عامة عن حقن SQL
تحدث عمليات حقن SQL عندما:
- تستخدم التعليمات البرمجية الخاصة بك بيانات غير مصححة من إدخال المستخدم في عبارات SQL
- يقوم مستخدم ضار بتضمين عناصر SQL في الإدخال بطريقة صعبة
- التعليمات البرمجية الخاصة بك تنفذ عناصر SQL هذه كجزء من عبارات SQL الشرعية
1.1.1. الأسئلة الشائعة حول حقن SQL
- ما هي خوادم SQL التي تتأثر بحقن SQL؟
قد تتأثر جميع خوادم SQL بإدخالات SQL: MySQL و MSSQL و Oracle و PostgreSQL والمزيد. - ما هي لغات البرمجة التي تتأثر بحقن SQL؟
قد تحدث حقن SQL في أي لغة برمجة. - ماذا يمكن أن تكون عواقب حقن SQL؟
قد يؤدي حقن SQL إلى تسرب البيانات ولكنه قد يؤدي أيضًا إلى اختراق النظام بالكامل. - ما مدى شيوع حقن SQL؟
تم العثور على حقن SQL بواسطة Acunetix في المتوسط في 8٪ من تطبيقات الويب. - هل الجدران النارية لتطبيقات الويب (WAF) تحمي من حقن SQL؟
لا ، فإن WAFs تجعل الأمر أكثر صعوبة على المهاجم لإرسال حمولات حقن SQL.
1.1.2. مثال بسيط على حقن SQL
الكود الخاص بك في PHP:
<?PHP
$userid = $_GET["userid"];
$query = "SELECT user FROM users WHERE userid = $userid;";
$result = pg_query($conn, $query);
?>
طلب المهاجم:
http://www.example.com/test.php؟userid=0 ؛ حذف من المستخدمين حيث 1
تعالج التعليمات البرمجية الخاصة بك استعلام SQL التالي:
$query = "SELECT user FROM users WHERE userid = 0; DELETE FROM users WHERE 1;";
نتيجة لذلك ، إذا كان لدى المستخدم الحالي (مستخدم قاعدة البيانات الحالي) أذونات مناسبة ، فسيتم استخدام المستخدمين تم مسح الجدول.
1.2 أنواع حقن SQL
1.2.1. إدخال SQL داخل النطاق: إدخال SQL المستند إلى الأخطاء
- ينشئ المهاجم حقنة SQL لجعل عرض الواجهة الخلفية خطأ
- ترجع النهاية الخلفية خطأ إلى المهاجم
- يستخدم المهاجم المعلومات الواردة في الخطأ لتصعيد الهجوم
- يستخدم هذا النوع من إدخال SQL للوصول إلى معلومات حساسة مثل نوع قاعدة البيانات وأسماء الملفات والمزيد
مثال:
- الحمولة:
http://testphp.vulnweb.com/listproducts.php؟cat=1 ′ - النتيجة: يعرض تطبيق الويب الخطأ التالي في المستعرض:
خطأ: لديك خطأ في بناء جملة SQL الخاص بك ؛ تحقق من الدليل الذي يتوافق مع إصدار خادم MySQL الخاص بك للحصول على الصيغة الصحيحة لاستخدامها بالقرب من “” في السطر 1 تحذير: يتوقع mysql_fetch_array () أن تكون المعلمة 1 عبارة عن مورد ، قيمة منطقية معطاة في /hj/var/www/listproducts.php في السطر 74
1.2.2. إدخال SQL داخل النطاق: إدخال SQL المستند إلى الاتحاد
- يستخدم المهاجم اتحاد شرط في الحمولة
- يجمع محرك SQL بين المعلومات الحساسة والمعلومات الشرعية التي يجب أن يعرضها تطبيق الويب
- يعرض تطبيق الويب معلومات حساسة
مثال:
1.2.3. حقن SQL الأعمى: حقن SQL المستند إلى منطقية
- يرسل المهاجم العديد من الحمولات التي تجعل تطبيق الويب يُرجع نتيجة مختلفة اعتمادًا على ما إذا كان استعلام SQL يُرجع TRUE أو FALSE
- يستخلص المهاجم استنتاجًا من سلوك تطبيق الويب لكل حمولة
- غالبًا ما يستخدم هذا النوع من حقن SQL للتحقق مما إذا كان من الممكن إدخال أي حقن SQL أخرى ولكن يمكن استخدامه أيضًا للوصول إلى المعلومات الحساسة
مثال:
1.2.4. حقن SQL أعمى: إدخال SQL المستند إلى الوقت
- إذا لم يُرجع تطبيق الويب أخطاء وكانت المعلومات التي تم إرجاعها هي نفسها بالنسبة للحمولات المستندة إلى منطقية ، فإن المهاجم يرسل حمولة تتضمن أمر تأخير الوقت مثل SLEEP ، مما يؤخر الاستجابة بالكامل
- يستخلص المهاجم استنتاجًا من سلوك تطبيق الويب ويكرر العملية عدة مرات قدر الإمكان باستخدام وسيطات مختلفة
- غالبًا ما يستخدم هذا النوع من حقن SQL للتحقق مما إذا كان من الممكن إدخال أي حقن SQL أخرى
- يمكن أيضًا استخدام هذا النوع من حقن SQL ، على سبيل المثال ، لتخمين محتوى خلية قاعدة بيانات حرفًا في كل مرة باستخدام قيم ASCII مختلفة جنبًا إلى جنب مع تأخير زمني
مثال:
1.2.5. حقن SQL خارج النطاق:
- هذا النوع من حقن SQL ممكن فقط لبعض قواعد البيانات ، على سبيل المثال ، Microsoft SQL Server و Oracle.
- يشتمل المهاجم على أمر قاعدة بيانات خاص في الحمولة – يتسبب هذا الأمر في طلب إلى مورد خارجي (يتحكم فيه المهاجم)
- يراقب المهاجم محاولات الاتصال بالمورد الخارجي ، على سبيل المثال ، عمليات بحث DNS أو سجلات طلبات HTTP للمورد الخارجي
- إذا كان هناك طلب قادم بمجرد تنفيذ الحمولة ، فهذا يؤكد أن إدخال SQL ممكن
- يصل المهاجم إلى معلومات قاعدة البيانات ويمكنه إرسالها إلى مورد خارجي
مثال (Oracle):
- الحمولة:
1 || UTL_HTTP.request (“http://example.com/”) - النتيجة: تم تقديم طلب إلى example.com – يمكنك مراقبة مثل هذه الطلبات إذا كنت تتحكم example.com.
2. دفاع حقن SQL
2.1. استعلامات ذات معلمات (بيانات معدة)
- هذه التقنية متوفرة في العديد من لغات البرمجة
- بدلاً من تكوين الاستعلام باستخدام وظائف مثل
concat
أو غيرها من أشكال تسلسل السلاسل ، تتضمن سلسلة الاستعلام المعلمات - تستبدل مكتبة البيانات المعدة هذه المعلمات بالقيم التي يوفرها المستخدم ويتم تعقيمها ، بحيث يتم تمرير أوامر SQL وإدخال المستخدم (المعلمات) بشكل منفصل
2.1.1. مثال PHP
استخدام كائنات بيانات PHP (PDO):
$dbh = new PDO('mysql:host=localhost;dbname=database', 'dbuser', 'dbpasswd');
$query = "SELECT column_name FROM table_name WHERE id = :id order by column_name desc";
$sth = $dbh->prepare($query);
$sth->bindParam(':id', $_GET[“id”]);
$sth->execute();
$result = $sth->fetchColumn();
2.1.2. مثال جافا
int id = Integer.parseInt(id);
String query = "SELECT column_name FROM table_name WHERE id = ? order by column_name desc";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setInt(1,id);
ResultSet results = stmt.executeQuery();
2.2. الإجراءات المخزنة
- استخدم فقط إذا كانت لغة البرمجة الخاصة بك لا تدعم البيانات المعدة
- لتجنب حقن SQL ، يجب عليك استخدام عبارات معدة في الإجراءات المخزنة
- متاح فقط لمحركات قواعد البيانات التي تدعم الإجراءات المخزنة ولكن معظم المحركات الحديثة تدعمها
- يتم تحضير الاستعلام وتخزينه في محرك قاعدة البيانات
- يستدعي التطبيق الإجراء المخزن ويمرر المتغيرات إليه
2.2.1 مثال MySQL
إنشاء الإجراء:
CREATE PROCEDURE example(IN suppliedId VARCHAR(8))
BEGIN
SELECT column_name FROM table name WHERE id = suppliedId;
END
استدعاء الإجراء مع هوية شخصية = 1:
CALL example("1");
لن تعمل حمولة حقن SQL:
CALL example("0;DELETE FROM users WHERE 1");
2.2.2 مثال MSSQL
إنشاء الإجراء:
CREATE PROCEDURE dbo.example @id nvarchar(8)
AS
SELECT column_name FROM table name WHERE id = @id;
GO
استدعاء الإجراء مع هوية شخصية = 1:
EXEC database.dbo.example 1;
لن تعمل حمولة حقن SQL:
EXEC database.dbo.example 0;DELETE FROM USERS WHERE 1
3. موارد إضافية
احصل على أحدث محتوى حول أمان الويب
في بريدك الوارد كل أسبوع.