البرمجة الآمنة في لغة SQL Injections … PHP
الكاتب: ابراهيم بصه | 23 يوليو 2006
بسم الله الرحمن الرحيم ..
لقد تعرفنا على بالدرس السابق علـ CrossSite Scripting وطرق الحماية منه و كيفية الاستغلال الأولية
واليوم سوف نتكلم عن ما هو اخطر من الـ XSS وما يسمى بالـ SQL Injection ... وتعني بالعربية ( حقنة الـ سـ كـيو ال )
لماذا تسمى بالـ حقنة ؟
لقد سميت بالحقنة لأن من اكتشف هذا النوع سمها كذا :D ... لاكن السبب الرئيسي هو ان طريقة استغلالها تكون بحقن الاستعلام الرئيسي بـ استعلام آخر يغير مجرى الاستعلام الأول للوصول إلى بيانات ليس من حقك الاطلاع عليها
وليـست فقط الـ MySQL التي لها هذا النوع من الثغرات .. بل الـ Oracle & MS-SQL
ولكل واحدة طريقة استغلال .. فـ مثلاً طريقة استغلال الـ MS-SQL اهون بكثير من الـ MySQL لأنها توفر لك طرق لجلب اسماء الجداول و الحقول .. لاكن أكثر برمجيات الـ PHP تعتمد بشكل كبير على الـ MySQL لأنها تتوافق مع جميع السيرفرات وكما ذكرنا ان مكانيكية العمل هي حقن الاستعلام الرئيسي بـ استعلام آخر أو بدالة آخره تغير مجرى الاستعلام ..
اين من الممكن وجود هذا النوع من الثغرات ؟
من الممكن ايجاد هذا النوع من الثغرات في جميع برامج الـ PHP , ASP وغيرها التي تتعامل مع قواعد البيانات .. حتى بالبرامج التنفيذية على الـ Linux و غيره من الآنظمة .
** ودائما تذكر قبل البدء بكتابة برنامج تاكد من الناوحي الامنية و انك تجيد تفادي الثغرات إلى حد كبير ( ولا يوجد برنامج خالي من الثغرات ).
نبدا ...
انظر إلى الكود التالي :-
كما تلاحظ لقد قمنا بالاستعلام من الجدول ( Table ) عن محتوياته بشرط ان يعرض محتويات الحقول التي ( حقل الـ ID فيها يساوي الـ _GET[id] )
يكون الرابط على هذا الشكل :-
-
http://127.0.0.1/file.php?id=1
فرضا ...
لاكن لو اعطينا الـ ID قيمة وهمية أو غير موجوده مثل ( -99999 ) سوف يعرض البيانات بحقول فارغه ..
-
http://127.0.0.1/file.php?id=-99999
وعند استعمال الجملة ( UNION ) يتم تغير مجرى الاستعلام ما ان وجد البيانات فارغه ليستعلم عن شيء ليس من حقه الاتطلاع عليه
-
http://127.0.0.1/file.php?id=-99999 UNION SELECT username,password FROM admin/*
لا اريد التعمق بالستغلال لأن له شروط و له عدة طرق للوصول إلى البيانات .. لأن اوضح الطريقه فقط ..
الآن للحماية من هذه الثغره .. مثلما راينا ان المتغير id متغير رقمي .. لذلك يجب علينا استعمال الدالة intval() معه .. لتعيد القيمة الرقمية الحقيقية للمدخلات و هذه بعض الدوال المساعده ..
-
http://il.php.net/manual/en/function.intval.php
-
http://il.php.net/manual/en/function.is-numeric.php
وهناك فائدة لـ استعمال الدالتين .. الأوله تعيد القيمة الرقمية الحقيقية للمدخلات .. اما الثانية فهيه تتاكد من المتغير اذ كان رقمي حقيقي أو لا و تعود بقيمتين ( True OR False )
استعمال الداله الأولى للترقيعه :-
-
<?php $id=intval($_GET['id']); mysql_query("SELECT * FROM Table WHERE id=".$id."") or die(mysql_error()); ?>
استعمال الداله الثانية للترقيعه :-
-
<?php if(!is_numeric($_GET['id'])){ echo "STOP SQL Injection"; exit(); } mysql_query("SELECT * FROM Table WHERE id=".$id."") or die(mysql_error()); ?>
هذا بالـ نسبة للاستعمال مع الارقام .. اما السلاسل النصية فـ لها دوال آخرى
انظر إلى الكود التالي :-
هنا يتعامل مع سلسلة نصية و هي عبارة عن بريد الكتروني ..
-
http://127.0.0.1/file.php?id=me@devpedia.org
سوف يصبح الاستعلام هكذا :-
لاكن في حالة تم إضافة علامة الـ ' للـ استعلام سوف يصبح هكذا :-
ويظهر خطأ يعلمك بوجوده في الاستعلام .. و هنا تتم عملية كتابة الاتستغلال ( Exploit )
السلاسل النصية تاتي الحماية لها من ملف الـ php.ini في حال ان الـ magic_quotes_gpc = on
اما لو كانت الـ magic_quotes_gpc = off فـ عند ئذن يجب علينا استعمال دوال الـ addslashes() و دوال التاكد من ان المدخل بريد بـ مساعدة ( Regex )
الترقيع بـ استعمال الـ addslashes()
-
<? mysql_query("SELECT * FROM Table WHERE id='".addslashes($_GET['email'])."'") or die(mysql_error()); ?>
حيث تعمل هذه الدالة على إضافة الـ Slash \ لكل للعلامات التالية :- ' & "