English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
إذا سمح موقعك للمستخدمين بإدخال البيانات عبر صفحة الويب وإدراج محتوى الإدخال في قاعدة بيانات SQLite، فإنك تواجه مشكلة أمنية معروفة باسم اختراق SQL. سنتحدث في هذا الفصل عن كيفية منع حدوث هذا النوع من الهجمات، والتأكد من أمان السكربتات وجمل SQLite.
عادة ما تحدث الهجمات بالتحكم بالدخول عند طلب إدخال المستخدمين، مثل الحاجة إلى إدخال الاسم، ولكن إذا أدخل المستخدم جملة SQLite، فإن هذه الجملة ستتم تنفيذها في قاعدة البيانات دون وعي.
لا تثقوا أبداً في البيانات التي يقدمها المستخدمون، وتعاملوا فقط مع البيانات التي تم التحقق منها، يتم تنفيذ هذه القاعدة من خلال مطابقة النمط.
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){}} $db = new SQLiteDatabase('filename'); $result = @$db->query("SELECT * FROM users WHERE username = $matches[0]");} else { echo "username not accepted";}
لتوضيح المشكلة، انظر المقطع التالي-
$name = "Qadir'; DELETE FROM users;";@$db->query("SELECT * FROM users WHERE username = '{$name}'");
استدعاء الدالة هو لاسترجاع السجلات من جدول 'users' التي تطابق اسم المستخدم المحدد من قبل المستخدم. في الحالة الطبيعية،$name يحتوي فقط على أحرف الأبجدية والرقميات أو الفراغات، مثل النص 'ilia'. ولكن هنا، تم إضافة استعلام جديد كليًا إلى $name، مما سيؤدي إلى مشكلة كارثية: سيقوم استعلام الحذف المنسوب بإزالة جميع سجلات 'users'.
بالرغم من أن هناك واجهات قاعدة البيانات لا تسمح بتنفيذ أكثر من استعلام في نفس الدالة أو تنفيذ استعلامات متداخلة، فإن SQLite وPostgreSQL لا تزالان يقومان بتنفيذ استعلامات متداخلة، أي تنفيذ جميع الاستعلامات المقدمة في نص واحد، مما يؤدي إلى مشاكل أمنية خطيرة.
في لغات البرمجة مثل PERL وPHP، يمكنك التعامل بذكاء مع جميع أحرف التحويل. يقدم لغة البرمجة PHP دالة نصية لتحويل النصوص SQLite3::escapeString($string) و sqlite_escape_string() لتحويل الأحرف الخاصة التي تختلف عن SQLite.
ملاحظة: استخدم الدالة sqlite_escape_string() يتطلب إصدار PHP PHP 5 < 5.4.0。
الإصدارات الأعلى من PHP 5 >= 5.3.0، PHP 7 يستخدم الدالة أعلاه:
if (get_magic_quotes_gpc()) { $name = sqlite_escape_string($name); } $result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");
على الرغم من أن الكود يجعل إدخال البيانات آمنًا، إلا أنه يقدم مقارنة نصية بسيطة، في الاستعلام، بالنسبة للأعمدة التي تحتوي على بيانات ثنائية،LIKE الجملة غير متاحة.
يرجى ملاحظة أن dashes() لا يجب استخدامه في استعلامات SQLite لتحديد النصوص، لأنه قد يؤدي إلى ظهور نتائج غريبة عند استرجاع البيانات.