بسم الله الرحمن الرحيم ..
لقد تعرفنا على بالدرس السابق علـ CrossSite Scripting وطرق الحماية منه و كيفية الاستغلال الأولية
واليوم سوف نتكلم عن ما هو اخطر من الـ XSS وما يسمى بالـ SQL Injection ... وتعني بالعربية ( حقنة الـ سـ كـيو ال )

لماذا تسمى بالـ حقنة ؟
لقد سميت بالحقنة لأن من اكتشف هذا النوع سمها كذا :D ... لاكن السبب الرئيسي هو ان طريقة استغلالها تكون بحقن الاستعلام الرئيسي بـ استعلام آخر يغير مجرى الاستعلام الأول للوصول إلى بيانات ليس من حقك الاطلاع عليها
وليـست فقط الـ MySQL التي لها هذا النوع من الثغرات .. بل الـ Oracle & MS-SQL
ولكل واحدة طريقة استغلال .. فـ مثلاً طريقة استغلال الـ MS-SQL اهون بكثير من الـ MySQL لأنها توفر لك طرق لجلب اسماء الجداول و الحقول .. لاكن أكثر برمجيات الـ PHP تعتمد بشكل كبير على الـ MySQL لأنها تتوافق مع جميع السيرفرات وكما ذكرنا ان مكانيكية العمل هي حقن الاستعلام الرئيسي بـ استعلام آخر أو بدالة آخره تغير مجرى الاستعلام ..
اين من الممكن وجود هذا النوع من الثغرات ؟
من الممكن ايجاد هذا النوع من الثغرات في جميع برامج الـ PHP , ASP وغيرها التي تتعامل مع قواعد البيانات .. حتى بالبرامج التنفيذية على الـ Linux و غيره من الآنظمة .

** ودائما تذكر قبل البدء بكتابة برنامج تاكد من الناوحي الامنية و انك تجيد تفادي الثغرات إلى حد كبير ( ولا يوجد برنامج خالي من الثغرات ).
نبدا ...

انظر إلى الكود التالي :-

PHP:
  1. <?php   mysql_query("SELECT * FROM Table WHERE id=".$_GET['id']."") or die(mysql_error())?>

كما تلاحظ لقد قمنا بالاستعلام من الجدول ( Table ) عن محتوياته بشرط ان يعرض محتويات الحقول التي ( حقل الـ ID فيها يساوي الـ _GET[id] )

يكون الرابط على هذا الشكل :-

PHP:
  1. http://127.0.0.1/file.php?id=1

فرضا ...
لاكن لو اعطينا الـ ID قيمة وهمية أو غير موجوده مثل ( -99999 ) سوف يعرض البيانات بحقول فارغه ..

PHP:
  1. http://127.0.0.1/file.php?id=-99999

وعند استعمال الجملة ( UNION ) يتم تغير مجرى الاستعلام ما ان وجد البيانات فارغه ليستعلم عن شيء ليس من حقه الاتطلاع عليه

PHP:
  1. http://127.0.0.1/file.php?id=-99999 UNION SELECT username,password FROM admin/*

لا اريد التعمق بالستغلال لأن له شروط و له عدة طرق للوصول إلى البيانات .. لأن اوضح الطريقه فقط ..

الآن للحماية من هذه الثغره .. مثلما راينا ان المتغير id متغير رقمي .. لذلك يجب علينا استعمال الدالة intval() معه .. لتعيد القيمة الرقمية الحقيقية للمدخلات و هذه بعض الدوال المساعده ..

PHP:
  1. http://il.php.net/manual/en/function.intval.php
PHP:
  1. http://il.php.net/manual/en/function.is-numeric.php

وهناك فائدة لـ استعمال الدالتين .. الأوله تعيد القيمة الرقمية الحقيقية للمدخلات .. اما الثانية فهيه تتاكد من المتغير اذ كان رقمي حقيقي أو لا و تعود بقيمتين ( True OR False )

استعمال الداله الأولى للترقيعه :-

PHP:
  1. <?php   $id=intval($_GET['id'])mysql_query("SELECT * FROM Table WHERE id=".$id."") or die(mysql_error())?>

استعمال الداله الثانية للترقيعه :-

PHP:
  1. <?php  if(!is_numeric($_GET['id'])){    echo "STOP SQL Injection";    exit(); }  mysql_query("SELECT * FROM Table WHERE id=".$id."") or die(mysql_error())?>

هذا بالـ نسبة للاستعمال مع الارقام .. اما السلاسل النصية فـ لها دوال آخرى
انظر إلى الكود التالي :-

PHP:
  1. <?php   mysql_query("SELECT * FROM Table WHERE id='".$_GET['email']."'") or die(mysql_error())?>

هنا يتعامل مع سلسلة نصية و هي عبارة عن بريد الكتروني ..

PHP:
  1. http://127.0.0.1/file.php?id=me@devpedia.org

سوف يصبح الاستعلام هكذا :-

PHP:
  1. mysql_query("SELECT * FROM Table WHERE id='me@devpedia.org'

لاكن في حالة تم إضافة علامة الـ ' للـ استعلام سوف يصبح هكذا :-

PHP:
  1. mysql_query("SELECT * FROM Table WHERE id='me@devpedia.org''

ويظهر خطأ يعلمك بوجوده في الاستعلام .. و هنا تتم عملية كتابة الاتستغلال ( Exploit )
السلاسل النصية تاتي الحماية لها من ملف الـ php.ini في حال ان الـ magic_quotes_gpc = on
اما لو كانت الـ magic_quotes_gpc = off فـ عند ئذن يجب علينا استعمال دوال الـ addslashes() و دوال التاكد من ان المدخل بريد بـ مساعدة ( Regex )

الترقيع بـ استعمال الـ addslashes()

PHP:
  1. <?   mysql_query("SELECT * FROM Table WHERE id='".addslashes($_GET['email'])."'") or die(mysql_error())?>

حيث تعمل هذه الدالة على إضافة الـ Slash \ لكل للعلامات التالية :- ' & "