PDA

View Full Version : مقاله: 5 نکته امنیتی در مورد PHP



Nima NT
پنج شنبه 03 بهمن 1387, 23:41 عصر
1:از کار انداختن نمایش خطاها

بهتر این است که بعد از کار کد نویسی ،تست و دیباگ از نمایش خطاهایی که ممکن است در مراحل اجرای اسکریپت رخ بده جلوگیری کنید تا مانع سواستفاده های احتمالی بشید .
بهترین روش برای این کار استفاده از دستور زیر در خط اول اسکریپت هاست


error_reporting(0);2:از کار انداختن تنظیمات بد php

یکی از بهترین خصوصیات phpاین است که شما می توانید بدون تعریف متغیر ها ازشون استفاده کنید ، این یکی از محبوبترین قابلیت های php هست اما اگر این قابلیت با register_global ترکیب بشه می تواند یک مشکل امنیتی در برنامه ها ایجاد کنه
به کد زیر نگاه کنید این کد بعد تر اعتبار سنجی نام کاربری و پسورد اجازه دسترسی به بخش های دیگه رو میده


if( !empty( $_POST['username'] ) && $_POST['username'] == 'test' && !empty( $_POST['password'] ) && $_POST['password'] == "test123" )
{
$access = 1;
}
If ($access == 1)
{
Include "secret.html";
} خوب این اسکریپت کوچیک شاید از نظر یک برنامه نویس باتجربه بدون عیب به نظر برسه اما در واقع دارای یک باگ امنیتی هست ،توی شبکه در خواست کسی که می خواد لوگین کنه به صورت زیر ارسال میشه :
http://www.yoursite.tld/test.php=use...ssword=test123 (http://www.yoursite.tld/test.php=username=test&password=test123)
خوب این ورودی ها که به برنامه برسه فایل secret.html را اینکلود میکنیم.

مشکل اینجاست که یوزر فقط محدود به فرستادن اسم رمز و کلمه عبور نیست و می تواند هرچیزی را که بخواهد به رشته در خواست اضافه کند .یک مثال در این زمینه به صورت زیر هست :
http://www.yoursite.tld/test.php?username?access=1
حالا اگر کسی این برنامه رو به صورت بالا درخواست کنه دستور if($access == 1) مساوی true مشه و صفحه ی محرمانه را نمایش میده



راه اول مقابله با این مشکل مقدار دهی اولیه متغیر هاست
راه دوم ازکارانداختن register_global است
متاسفانه میشه با شبه دستور ini_set بر روی register_global تغییری ایجاد کرد و باید با فایل های .htaccess و php.ini برای سایت و فولدر های موجود در سایت این دستور را از کار انداخت
دستورات زیر را می توانید در فایل های مورد نظر بنویسبد



Disabling with .htaccess
php_flag register_globals 0
Disabling with php.ini
register_globals = Off
Magic Quotes (magic_quotes_gpc, magic_quotes_runtime, magic_quotes_sybase)این دستور هم برای کنترل اصلش به حروف معنی دار مانند تک کوتیشن (') و دوتا کوتیشن (")هاست که مانند بالا باید با استفاده از .htaccess و php.ini تنظیمش کرد


Disabling with .htaccess
php_flag magic_quotes_gpc 0 php_flag magic_quotes_runtime 0
Disabling with php.ini
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off 3:درستی ورودی های کاربر

معمولا بیشترین حمله ها به برنامه های تحت وب از طرف فرم ها یی است که تعامل بین برنامه با یوزر رو ایجاد می کنه همیشه باید ورودی ها رو به طور دقیق چک کرد مثلا در مثال زیر با استفاده از تابع preg_match ورودی ها رو چک می کنیم و در صورتی که طبق فرمولی که ما می خواستیم نبود پیام خطایی صادر می کند



if ( ! preg_match( "/^[0-9]{1,2}$/", $_GET['month'] ) )
{
// handle error
}
if ( ! preg_match( "/^[0-9]{1,2}$/", $_GET['day'] ) )
{
// handle error
}
if ( ! preg_match( "/^[0-9]{4}$/", $_GET['year'] ) )
{
// handle error
}4: Cross Site Scripting (XSS) های اضافه شده همراه ورودی

روش های ایجاد این نوع باگ خیلی زیاد هست و همش بر می گرده به هنر نفوذگر و می تونه روش های متفاوتی داشته باشه اما برای جلوگیری از بروز این نوع مشکلات یکی از بهترین روش ها استفاده از bbtag ها یا bb code هاست که یک تگ خود شما به دلخواه می گذارید سپس با استفاده از ریپلیس کردن تگ شما با تگ اصلی در html اونرو به حالت اصلی برگردانید



5:محافظت در برابر SQL Injection

همانطور که می دانید دستورات ورود و خروج اطلاعات از دیتابیس با استفاده از فرمان های زبان SQL نوشته می شود این دستور را مابین " یا ' قرار می دهیم و برای اجرا به تابع مجری میفرستیم حالا اگر همراه یکی از متغیر هایی که قرار در SQL مورد نظر ادقام بشه یک " یا ' اضافی باشه حالت اتمام رشته رو بهم میزنه و میشه از این طریق دستوراتی که مد نظر برنامه نویس نبوده رو اجرا کرد و به اطلاعات محرمانه درون دیتابیس رسید مثلا فرض کنید ' OR 1=1 را همراه یک کوئری که یوزر و پسورد را چک می کند بفرستیم .نتیجه رو حتما می تونید حدث برنید!
یکی از توابعی که برای جلوگیری از همچین مشکلاتی استفاده می شود تابع : mysqli_real_escape_string هست که در زیر یک مثال از آن را می بینید



$username = mysqli_real_escape_string( $GET['username'] );
mysql_query( "SELECT * FROM tbl_members WHERE username = '".$username."'");نکته : توابع و راه حل های زیادی در کل این 5 مشکل وجود دارند که به یاری برنامه نویس میرسند اما من به آنها اشاره نکردم چون از حوصله مقاله خارج بود

Yousha
جمعه 04 بهمن 1387, 01:19 صبح
سلام،
تشکر از مقاله مفیدتون.
عزیز 2 تا نکته:


error_reporting(0);

100% اشتباه هستش! شما بدون خطا می نویسید، بدون خطا هم راه اندازی می کنید! پس باید Handing کنید نه Ignoring!!


@error_reporting(E_ALL ^ E_NOTICE);

و در این:


magic_quotes_runtime= Off

هر دو حالت کاربرد دارند. که معمولاً شرط میزارن. اگر Off سپس... اگر On سپس... .
...
موفق باشید.

yaqubian
جمعه 04 بهمن 1387, 18:21 عصر
دوست عزیز
لطفا موارد مهمی که به ذهنتون می رسه رو در پست tip های برنامه نویسی که قبلا گذاشته شده قرار بدید.
http://barnamenevis.org/forum/showthread.php?t=135766&highlight=tip
موفق باشید