البرمجة الآمنة في لغة SQL Injections … PHP

مدرج تحت قسم: دروس
23 يوليو 2006

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

لماذا تسمى بالحقنة؟

لقد سميت بالحقنة لأن من اكتشف هذا النوع سمها هكذا، لكن السبب الرئيسي هو ان طريقة استغلالها تكون بحقن الاستعلام الرئيسي باستعلام آخر يغير مجرى الاستعلام الأول للوصول إلى بيانات ليس من حقك الاطلاع عليها. وليـست فقط MySQL التي لها هذا النوع من الثغرات، بل Oracle & MS-SQL.

ولكل واحدة طريقة استغلال، فمثلاً طريقة استغلال MS-SQL أهون بكثير من MySQL، لأنها توفر لك طرق لجلب اسماء الجداول و الحقول، لكن أكثر برمجيات PHP تعتمد بشكل كبير على MySQL لأنها تتوافق مع جميع السيرفرات،  وكما ذكرنا ان مكانيكية العمل هي حقن الاستعلام الرئيسي باستعلام آخر، أو بدالة أخرى، تغير مجرى الاستعلام.

أين من الممكن وجود هذا النوع من الثغرات؟

من الممكن ايجاد هذا النوع من الثغرات في جميع برامج PHP ، ASP وغيرها التي تتعامل مع قواعد البيانات، حتى بالبرامج التنفيذية على Linux و غيره من الآنظمة. ودائما تذكر قبل البدء بكتابة برنامج من النواحي الأمنية وأنك تجيد تفادي الثغرات إلى حد كبير، ولا يوجد برنامج خالي من الثغرات.

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

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

كما تلاحظ لقد قمنا بالاستعلام من الجدول ( 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());
?>

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

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

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

http://127.0.0.1/file.php?id=me@almashroo.com

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

mysql_query("SELECT * FROM Table WHERE id='me@almashroo.com'

لكن في حالة تم إضافة علامة التنصيص ” ‘ ” للاستعلام، سوف يصبح هكذا:

mysql_query("SELECT * FROM Table WHERE id='me@almashroo.com''

ويظهر خطأ يعلمك بوجوده في الاستعلام وهنا تتم عملية كتابة الاتستغلال ( 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 \ لكل للعلامات التالية:

' & "

للكاتب Dev.Moh Sh

  • Share/Bookmark

التعليقات (2) على ”البرمجة الآمنة في لغة SQL Injections … PHP“

  1. عفواً أخي الكريم ,,

    دالة addslashes غير كافيه للحماية من الـ SQL Injection

    دالة addslashes بالإمكان تجاوزها , خصوصاً إذا كان الترميز هو العربية , الحل الأمثل هو إستخدام دالة mysql_real_escape_string

    :)

  2. محمد

    بارك الله فيكم يا أخوة

أضف تعليقك




يمكنك استخدام الوسوم التالية في التعليق: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


* حقول مطلوبة