PDA

View Full Version : امنیت صفحات در آدرس بار



Bahram0110
سه شنبه 09 مرداد 1386, 12:22 عصر
سلام
ببخشید عنوان بهتری به ذهنم نرسید


اگه من کارهایی که می خوام تو هر صفحه انجام بدم رو تو آدرس بار نشون بدم


http://. . ./index.php?page=admin&act=deleteall


چه مشکلی ممکنه پیش بیاد؟
اگه از urlencode استفاده کنم چطوره؟
روش بهتری سراغ ندارید؟

alireza82
سه شنبه 09 مرداد 1386, 15:09 عصر
سلام این مقاله ای از ایران php به آدرس iranphp.net
چون خیلی کامل تر از اون چیزایی بود که من میخوام بگم یعنی با 4 تا مثال و به صورت معتبر تر هم گفته اول مطلب اونجا رو میزارم
نکته امنیتی شماره سوم حملات موسوم به
SQL Injection
پیش از هر چیز سعی می‌کنم تعریفی از SQL Injection بیاورم این خیلی مهمه که بدونیم معنی این کلمه چیست این واژه به معنای تزریق SQL هست و خوب فکر می کنم دیگه حالا بشه حدس زد که این یعنی چی. یعنی اینکه یک کسی یک طوری یک چیزی رو به یک پایگاه داده SQL تزریق می کنه تزریق همیشه یادآور اینه که ماده ای خارجی که از جنس مقصد نیست به اون وارد می شه و این واقعا همون چیزیه که اتفاق میفته حالا با بیانی ساده آغاز می‌کنیم و به سراغ این می‌رویم که اگر برنامه‌های ما در مقابل این نوع حملات ضعف داشته باشند چگونه می‌توانند مورد حمله واقع شوند.
در واقع سه نوع حمله از این دست وجود دارند که دوتا از اونها مد نظر ما هستند
1- حملاتی که ناشی از اشتباه در فیلترینگ گریزکارکترها(escape characters)هستند
2- حملاتی که ناشی از اشتباه در نوع داده هستند
3- حملاتی که به حفره های ذاتی پایگاه های داده مربوط می‌شوند
پر واضح است که دو دسته اول مدنظر ماست که ادامه به بررسی اونها خواهیم پرداخت.
خوب اجازه بدهید در مورد اولی مثالی ببینیم



mysql_query('SELECT * FROM user WHERE username = "' . $_GET['username'] . '");

همونطوری که مشاهده می کنیم مانند همیشه خیلی عادی دارید نام کاربری که کاربر براتون با متد GET پست کرده رو جستجو می کنید که اگر یافت کردید به اون کاربر اجازه ورود بدید هدفمون اصلا این نیست که این کد رو پیچیده کنیم مثلا شما با خودتون بگین که اگر من باشم حتما با POST می فرستم و حتما پسورد را هم چک می کنم و حتما پسورد را دوبار md5 می کنم زیرا که اصلا حفره در اینجا نیست تصور کنید که یک نفوذگر(نه هکر) چنین چیزی را ارسال کند:

' OR '1'='1

و نتیجه نهایی در پرس و جوی SQL چنین می شود



mysql_query('SELECT * FROM user WHERE username = "' . ' OR '1'='1 . '");

خوب حالا نظرتون چیه!
می دونین مشکل اینجاست که قضیه به این سادگی ها هم ختم نمی شه و می شه یک نفوذگر ماهر ده ها مورد دیگر رو هم مورد استفاده قرار بده بطور مثال:



a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '%

که نتیجه تعصف برانگیز


mysql_query('SELECT * FROM user WHERE username = "' . a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '%
. '");

را به همراه خواهد داشت موارد دیگر مانند بوجود آوردن خطاها و گرفتن اطلاعات بدست آوردن نسخه پایگاه داده اجرا کردن کدها و مباحث پیشرفته SQL Injection رو نام برد که در هر مورد سخنان زیادی می شه گفت حالا اجازه دهید که به سراغ حفره دوم برویم :

mysql_query("SELECT * FROM user WHERE id = " + variable + ";");
واضح است که برنامه نویس در اینجا انتظار دارد که متغیری عددی در جای variable وارد گردد حال اگر بدون کنترل کردن نوع داده این کد را در اختیار کاربران بگذارد به چنین چیزی روبرو می شود
1;DROP TABLE users
و احتمالا دیگر نیازی نیست که بگویم بعدا چه اتفاقی خواهد افتاد خوب حالا چه باید کرد؟
حقیقت این است که اگر حفره های امنیتی عموما کابوسی وحشت ناک بشمار می آیند اما پیش گیری از آنها بسیار ساده است دو کد برای شما ذکر می کنم که منبع اون ها یکی از سایتهایی بود که چند وقت پیش در این زمینه مطالعه می کردم و الان آدرس اونها در ذهنم نیست
در مورد حفره اول تابعی را می نویسیم که بسیار ساده و در عین حال محکم و قابل اعتماد است

function sql_quote( $value )




{

if( get_magic_quotes_gpc() )
{
$value = stripslashes( $value );
}
//check if this function exists
if( function_exists( "mysql_real_escape_string" ) )
{
$value = mysql_real_escape_string( $value );
}
//for PHP version < 4.3.0 use addslashes
else
{
$value = addslashes( $value );
}
return $value;
}
و نحوه استفاده از اون هم بسیار ساده است
$username = $_POST['username'];
query = "SELECT * FROM users WHERE username='" . sql_quote($username) . "'";







در مورد نکته دوم هم که کلاس امیرمحمد عزیز رو مورد استفاده قرار دادم که یکی از مجموعه های بدرد بخور PEAR هست و به آدرس http://pear.php.net/package/Validate می تونین اون رو دریافت کنین و آدرسی که در کد هست رو به مسیر دلخواهی که این فایل درون قرار داره تغییر بدین





//init validate object
include_once('your_path_to_pear_directory/Validate.php');
$validate = &new Validate();

//get POST variables
$username = $_POST['username'];
$email = $_POST['email'];
$age = $_POST['age'];

//validate username, only alphanumeric and space characters are allowed
//VALIDATE_ALPHA, VALIDATE_NUM, VALIDATE_SPACE constants are defined in Validate class.
if( !$validate->string( $username, array('format'=>VALIDATE_ALPHA . VALIDATE_NUM . VALIDATE_SPACE ) ) )
{
//throw some username error
}
//validate email
if( !$validate->email( $email ) )
{
//throw some email error
}
//validate age, only numbers between 0 and 100 are allowed
if( !$validate->number( $age, array( 'min'=>0, 'max'=>100 ) ) )
{
//throw some age error
}

خوب حالا چند مورد اضافی هم باید ذکر کنم در مورد کد اول چند تابع می بینید که برای پاسخ به حس کنجکاوی شما توضیحی براشون نمیارم ولی در پایگاه های داده گوناگون توابع در نظر گرفته شده تقریبا به همین شکل هستند
MySQL: mysql_real_escape_string()
PostgreSQL: pg_escape_string()
SQLite: sqlite_escape_string()

راه حل خوب دیگری که حتما باید ذکر گردد استفاده از PDO است که در اینجا مجالی برای شرح آن نیست و توضیحاتی در این زمینه را می تونین در
http://ir2.php.net/pdo
در کل بهتر هست همسشه رفر ای که اطلاعات ازش میاد چک کنید و از توابع امن ساز db مثل اداسلش و ... استفاده کنید.
اگر قرار نیست کاربر اطلاعاتی رو ببینه یا اون اطلاعات مهم هستند از post استفاده کنید. اگر هم از urlencode استفاده میکنید باز طرف میتونه البته دیگه مبتدی ها نه میتونه با urldecode اسم ها رو و متغییر ها رو گیر بیاره پس تو اونجا هم ریفر اطلاعات رو چک کنید.
اگر دوستان مطلب کامل تری دارند خوشحال میشیم استفاده کنیم.
3 تا مقاله با عنوان نکته امنیتی رو سایتشون گذاشتن که خوندنش اون خالی از لطف نیست.
موفق باشید