PDA

View Full Version : انواع حمله های نفوذ و سوءاستفاده از صفحات وب



eshpilen
جمعه 19 فروردین 1390, 23:25 عصر
SQL Injection
این حمله معرف همگان هست. این حمله برای نفوذ در کوئری های دیتابیس اجرا شده و اجرای کوئری های دلخواه نفوذگر استفاده میشه.

XSS
توسط این حمله کدهای اسکریپت سمت کلاینت (جاوااسکریپت یا vbscript) مورد نظر نفوذگر از طریق صفحات سایت شما اجرا میشن. یعنی یجوری اسکریپت ها رو در صفحات تزریق میکنه.
این حمله ای مستقیم به خود سایت نیست، بلکه حمله به کاربران سایت هست و با این روش مثلا محتویات کوکی های لاگین یا سشن کاربران رو میشه سرقت کرد و نفوذگر بعد از اینکار میتونه بجای اونا لاگین بشه یا درصورتی که اطلاعات مهم دیگری هم در کوکی ها باشه از اون اطلاعات سوء استفاده های دیگری هم بکنه.

XSRF
بوسیلهء این حمله یک دستور/عملیات از طرف کاربر بدونه اینکه خودش خبر داشته باشه میتونه در سایتی که احتمالا کاربر در اون لاگین هست اجرا بشه. یعنی کاربر بدون اینکه متوجه بشه آدرسی از سایت هدف رو که عملیات خاصی انجام میده در مرورگر خودش تحت ظاهرا سایت دیگری باز میکنه. اینم باز حملهء مستقیمی به خود سایت نیست، بلکه به کاربران سایت حمله میشه.

Header Injection
این حمله به فرمهای تماسی که از ایمیل استفاده میکنن و کاربر ایمیل خودش رو در فیلد مربوطه در فرم وارد میکنه و بعد این آدرس ایمیل بدون ولیدیت کردن در قسمت هدرهای تابع mail درج میشه (*) صورت میگیره که بوسیلهء این روش میتونن از طریق فرم تماس شما به هرکس دیگری که میخوان ایمیل ارسال کنن و این ایمیل از طرف سایت شما ارسال میشه، بنابراین به این طریق مسئولیت گردن سایت شما میاد و ضمنا میتونن با ایمیل های جعلی که ظاهرا از طرف سایت شماست اقدام به فریب و کلاهبرداری از کاربران بکنن. به این روش حتی میشه ایمیل های دارای ضمیمه هم ارسال کرد و مثلا ضمیمه ممکنه فایل اجرایی یک برنامهء جاسوسی باشه.
*: در کدهای ارسال ایمیل در فرم تماس، درج ایمیل کاربر در قسمت هدرهای ایمیل از این جهت صورت میگیره که موقعی که ایمیل دریافت شده رو میخونید و دکمه Reply رو در نرم افزار ایمیل خودتون برای پاسخگویی به کاربر مورد نظر میزنید، آدرس کاربر بصورت خودکار در قسمت آدرس دریافت کننده درج بشه.

سرقت session یا اطلاعاتش
در راحتترین و خطرناک ترین سناریو در این حمله، فرد دیگری که با شما هاست مشترکی داره میتونه براحتی سشن کاربران شما رو سرقت کنه و خودش رو بجای اونها به سایت وارد کنه یا اطلاعات درون سشن کاربران سایت شما رو بخونه (هرچیزی که شما در سشن ذخیره کرده باشید). ضمنا حتی ممکنه سشن خود شما رو که بعنوان ادمین لاگین هستید سرقت کنه و بنابراین دسترسی ادمین به نرم افزار سایت شما بدست بیاره.
این مشکل در تمامی نصب ها با تنظیمات پیشفرض PHP میتونه وجود داشته باشه که باید به روشهایی اون رو برطرف کرد (البته اگر در برنامه تون از سشن استفاده میکنید).

کرک هش پسوردها
در این روش نفوذگر از روی هش پسوردهای کاربران به خود پسوردها میرسه که نه تنها امنیت اکانت فعلی کاربر در سایت رو از بین میبره بلکه میتونه برای حمله به اکانتهای دیگر کاربر در سایتهای دیگر هم مورد استفاده قرار بگیره (خیلی از کاربران از یک پسورد برای چند اکانت و در سایتهای مختلف استفاده میکنن).

register_globals
البته این خودش یک حمله نیست ولی یک ویژگی قابل سوء استفاده هست که باید یا غیرفعالش کرد یا کدهای لازم رو با توجه به خطرش نوشت.

دسترسی مستقیم به فایلهای اینکلودی
باید از دسترسی مستقیم از طریق وب به فایلهای اینکلودی خودتون جلوگیری کنید.

Remote file inclusion
به این روش نفوذگر میتونه فایل مورد نظر خودش رو (که میتونه روی همون هاست یا هاست دیگری باشه) بجای فایلهای برنامهء ما اینکلود کنه.

Session fixation
به این روش نفوذگر میتونه قربانی رو فریب بده تا با Session ID ای که نفوذگر تعیین میکنه یا برای نفوذگر مشخص هست، در سایت مورد نظر لاگین بکنه و بعد نفوذگر میتونه با استفاده از اون Session ID بجای قربانی در سایت مورد نظر لاگین بشه.

--------------------------------------------------------------------------------------

خب منتظریم تا دوستان دیگر حمله های دیگری رو که میشناسن ذکر کنن و اگر تونستن به همین شکل توضیح مختصری هم راجع به اونها بدن.
بعدا که لیست حمله ها کامل شد احتمالا روشهای استاندارد جلوگیری از اونا رو هم مطرح میکنیم.

phpweb
شنبه 20 فروردین 1390, 11:32 صبح
SQL Injection
این حمله معرف همگان هست. این حمله برای نفوذ در کوئری های دیتابیس اجرا شده و اجرای کوئری های دلخواه نفوذگر استفاده میشه.

XSS
توسط این حمله کدهای اسکریپت سمت کلاینت (جاوااسکریپت یا vbscript) مورد نظر نفوذگر از طریق صفحات سایت شما اجرا میشن. یعنی یجوری اسکریپت ها رو در صفحات تزریق میکنه.
این حمله ای مستقیم به خود سایت نیست، بلکه حمله به کاربران سایت هست و با این روش مثلا محتویات کوکی های لاگین یا سشن کاربران رو میشه سرقت کرد و نفوذگر بعد از اینکار میتونه بجای اونا لاگین بشه یا درصورتی که اطلاعات مهم دیگری هم در کوکی ها باشه از اون اطلاعات سوء استفاده های دیگری هم بکنه.

XSRF
بوسیلهء این حمله یک دستور/عملیات از طرف کاربر بدونه اینکه خودش خبر داشته باشه میتونه در سایتی که احتمالا کاربر در اون لاگین هست اجرا بشه. یعنی کاربر بدون اینکه متوجه بشه آدرسی از سایت هدف رو که عملیات خاصی انجام میده در مرورگر خودش تحت ظاهرا سایت دیگری باز میکنه. اینم باز حملهء مستقیمی به خود سایت نیست، بلکه به کاربران سایت حمله میشه.

Header Injection
این حمله به فرمهای تماسی که از ایمیل استفاده میکنن و کاربر ایمیل خودش رو در فیلد مربوطه در فرم وارد میکنه و بعد این آدرس ایمیل بدون ولیدیت کردن در قسمت هدرهای تابع mail درج میشه (*) صورت میگیره که بوسیلهء این روش میتونن از طریق فرم تماس شما به هرکس دیگری که میخوان ایمیل ارسال کنن و این ایمیل از طرف سایت شما ارسال میشه، بنابراین به این طریق مسئولیت گردن سایت شما میاد و ضمنا میتونن با ایمیل های جعلی که ظاهرا از طرف سایت شماست اقدام به فریب و کلاهبرداری از کاربران بکنن. به این روش حتی میشه ایمیل های دارای ضمیمه هم ارسال کرد و مثلا ضمیمه ممکنه فایل اجرایی یک برنامهء جاسوسی باشه.
*: در کدهای ارسال ایمیل در فرم تماس، درج ایمیل کاربر در قسمت هدرهای ایمیل از این جهت صورت میگیره که موقعی که ایمیل دریافت شده رو میخونید و دکمه Reply رو در نرم افزار ایمیل خودتون برای پاسخگویی به کاربر مورد نظر میزنید، آدرس کاربر بصورت خودکار در قسمت آدرس دریافت کننده درج بشه.

--------------------------------------------------------------------------------------

خب منتظریم تا دوستان دیگر حمله های دیگری رو که میشناسن ذکر کنن و اگر تونستن به همین شکل توضیح مختصری هم راجع به اونها بدن.
بعدا که لیست حمله ها کامل شد احتمالا روشهای استاندارد جلوگیری از اونا رو هم مطرح میکنیم.

دوست عزیز من بعد از پست مرجع کاراکترهای مخرب مانند x0A \xFF %00 (http://barnamenevis.org/showthread.php?281805) تصمیم داشتم که انواع خطرات اینترنتی به وبسایتها و کاربران وبسایتها رو معرفی کنم. البته هنوز لیست کاراکترهایی که می تونن کاربرد مخربی داشته باشن رو بدست نیاوردم و باید لیست این کاراکترها رو پیدا کنم.

در مورد روشهایی که بیان کردید باید بگم که در مورد سرقت سسشن ها (سرقت نشست) چیزی نگفتید.

برای توضیحات تکمیلی در مورد این نوع حمله و راههای مقابله با اون به این لینک (http://cyberrabbits.net/485/save-session-in-db/#more-485)مراجعه کنید.

phpweb
شنبه 20 فروردین 1390, 11:36 صبح
یادم رفت بگم که توی تحقیقاتی که انجام دادم، بغیر از راههای شناخته شده برای نفوذ، بعضی از ریزه کاری هست که توجه نکردن به اون ها باعث می شه سایت ضعف داشته باشه.

تصمیم دارم در این مورد یه آموزش کامل توی وب سایت قرار بدم.

eshpilen
شنبه 20 فروردین 1390, 12:27 عصر
در مورد روشهایی که بیان کردید باید بگم که در مورد سرقت سسشن ها (سرقت نشست) چیزی نگفتید.

آهان خیلی ممنون. اینو یادم رفته بود.
البته من خیلی احتمال میدادم که شاید این مشکل در نسخه های اخیر PHP (نسخهء ۵) حل شده باشه، چون فکر میکنم حل کردنش برای طراحان PHP نباید چندان سخت باشه.
الان یکسری تست روی هاستی که زیر دستم بود کردم دیدم ظاهرا اوضاع به همون منواله و سشن ها کماکان در دایرکتوری مشترک /tmp ذخیره میشن.
جدا نمیدونم چرا فکری برای این ضعف بزرگ نمیکنن و بنظر بنده از اولش هم این یه ضعف و اهمال در طراحی PHP بوده. آخه از کی تاحالا طبیعی بوده که کاربران دیگه بتونن براحتی به دیتای دیگران دسترسی داشته باشن؟ مثلا درمورد سشن های ASP.NET هم آیا همینطوره؟
بهرحال ممنون که این مورد رو هم یادآوری کردید.
مورد دیگه ای هم اگر میدونید ذکر کنید.


یادم رفت بگم که توی تحقیقاتی که انجام دادم، بغیر از راههای شناخته شده برای نفوذ، بعضی از ریزه کاری هست که توجه نکردن به اون ها باعث می شه سایت ضعف داشته باشه.

تصمیم دارم در این مورد یه آموزش کامل توی وب سایت قرار بدم. توی کدوم سایت؟
خب در همین فروم قرار بده. اصلا میتونی در همین تاپیک هم بذاری.
بحث و درج مطلب یک طرفه فایده نداره. هرچی افراد بیشتری بتونن بررسی و بحث کنن و نظر و تجربشون رو بگن بهتره.
هدف باید یادگیری باشه. حالا هر مطلبی میخواد باشه. واسه همین برای من فرقی نمیکنه در این تاپیک مطالب ظاهرا بی ربط هم اگر مطرح بشه. بنده نهایتش چنتا دونه مطلب میذارم که خودم از قبل بلدم و اگر دیگران چیزی نگن آدم چیزی بیشتری یاد نمیگیره و و متوجه ضعفهاش نمیشه. بنابراین این تاپیک و موضوعش به خودی خود برای من هیچ ارزشی نداره.

phpweb
شنبه 20 فروردین 1390, 12:59 عصر
آهان خیلی ممنون. اینو یادم رفته بود.
البته من خیلی احتمال میدادم که شاید این مشکل در نسخه های اخیر PHP (نسخهء ۵) حل شده باشه، چون فکر میکنم حل کردنش برای طراحان PHP نباید چندان سخت باشه.
الان یکسری تست روی هاستی که زیر دستم بود کردم دیدم ظاهرا اوضاع به همون منواله و سشن ها کماکان در دایرکتوری مشترک /tmp ذخیره میشن.
جدا نمیدونم چرا فکری برای این ضعف بزرگ نمیکنن و بنظر بنده از اولش هم این یه ضعف و اهمال در طراحی PHP بوده. آخه از کی تاحالا طبیعی بوده که کاربران دیگه بتونن براحتی به دیتای دیگران دسترسی داشته باشن؟ مثلا درمورد سشن های ASP.NET هم آیا همینطوره؟
بهرحال ممنون که این مورد رو هم یادآوری کردید.
مورد دیگه ای هم اگر میدونید ذکر کنید.
توی کدوم سایت؟
خب در همین فروم قرار بده. اصلا میتونی در همین تاپیک هم بذاری.
بحث و درج مطلب یک طرفه فایده نداره. هرچی افراد بیشتری بتونن بررسی و بحث کنن و نظر و تجربشون رو بگن بهتره.
هدف باید یادگیری باشه. حالا هر مطلبی میخواد باشه. واسه همین برای من فرقی نمیکنه در این تاپیک مطالب ظاهرا بی ربط هم اگر مطرح بشه. بنده نهایتش چنتا دونه مطلب میذارم که خودم از قبل بلدم و اگر دیگران چیزی نگن آدم چیزی بیشتری یاد نمیگیره و و متوجه ضعفهاش نمیشه. بنابراین این تاپیک و موضوعش به خودی خود برای من هیچ ارزشی نداره.

بنظرم بهتره که اون لینک رو مطالعه کنید و روشهای مقابله رو این مشکل بدست بیارید. تنها مشکل ذخیره شدن سسشن ها توی دایرکتوری تمپ نیست، از راههای دیگه هم می شه سسشنها رو دزدید. از طریق سرقت کوکی های ذخیره شده توی سیستم کاربر می شه اینکار رو کرد و . . .

بنظرم به اندازه کافی توی اون وبلاگ در این مورد توضیح داده شده.

در مورد اینکه گفتید مطلب آموزشیم رو کجا مطرح می کنم باید بگم که منظرم از وب سایت همین فروم برنامه نویس بود.

اما ظاهرا شما کمی عجول هستید. به هرحال اول باید بتونم لیست تمام کاراکترهای مخرب رو بدست بیارم. :چشمک:

می خوام پله پله جلو تر برم تا هیچ نکته ای باقی نمونه (حتی یه کاراکتر به ظاهر بی خطر).

mamali-mohammad
شنبه 20 فروردین 1390, 13:30 عصر
ممنون دوست عزیز
لطفا نحوه جلوگیری ازش هم بگید
که چه راهکارهای امنیتی میشه انجام داد

eshpilen
شنبه 20 فروردین 1390, 14:01 عصر
بنظرم بهتره که اون لینک رو مطالعه کنید و روشهای مقابله رو این مشکل بدست بیارید. تنها مشکل ذخیره شدن سسشن ها توی دایرکتوری تمپ نیست، از راههای دیگه هم می شه سسشنها رو دزدید. از طریق سرقت کوکی های ذخیره شده توی سیستم کاربر می شه اینکار رو کرد و . . . بنظرم مشکل بزرگ و اولش همونه.
قبلا درمورد راهکارهاش هم مطالعه داشتم و در پروژهء خودم بطور مثال از روش تغییر مکان ذخیرهء فایلهای سشن و همچنین روشهایی مثل Regenerate کردن سشن برای امنیت بیشتر استفاده کردم.
ضمنا سرقت کوکی از روی سیستم کاربر چیزی نیست که مختص سشن باشه و به تمام کوکی های محتوی اطلاعات مهم (مثل کلید لاگین) مربوط میشه. یکی از روشهاش هم همون XSS هست که ذکر کردیم. شما روش دیگری سراغ داری نام ببر (در منبعی که گفتی چیز بیشتری نیامده).


اما ظاهرا شما کمی عجول هستید. به هرحال اول باید بتونم لیست تمام کاراکترهای مخرب رو بدست بیارم. :چشمک:

می خوام پله پله جلو تر برم تا هیچ نکته ای باقی نمونه (حتی یه کاراکتر به ظاهر بی خطر).
بازم این بحث کاراکترها. نمیدونم چه اهمیتی داره. میبینی که هیچکس هم نمیاد چیزی اضافه کنه. تازه دست آخر از کجا میتونی مطمئن بشی واقعا همهء کاراکترها رو فهمیدی؟ تا کی میخوای منتظر بشی؟
نوع این کاراکترها هم متغییر هست. مثلا برای MySQL کاراکترهای مخرب یک چیز هست، برای PostgreSQL ممکنه یه سری کاراکتر دیگه باشه.
مهم خود حملات هستن و روش استاندارد جلوگیری از اونها. خیلی وقتا اصلا نیازی نیست کاراکترهای مورد نظر رو هم دقیقا بدونی. مثلا من وقتی از mysql_real_escape_string استفاده کنم کافیه و نیازی به دونستن تک تک کاراکترهای مخرب ندارم.
بنظرم شما داری راه رو سر و ته طی میکنی! اول میخوای کاراکترها رو بدست بیاری بعد ببینی کاراکتر مال کجاست و چطوری جلوش رو بگیری. بخاطر همین که این راه سر و ته هست و این کاراکترها متغییر و زیاد هستن و به خودی خود اهمیتی هم ندارن هست که هیچ منبعی هم پیدا نمیکنی که مشابه این کار رو انجام داده باشه.
خلاصه از ما گفتن بود. حالا منتظر باش تا پیغمبری چیزی بیاد لیست کاراکترهات رو کامل کنه و مهر نهایی بزنه روش :لبخند:

eshpilen
شنبه 20 فروردین 1390, 23:06 عصر
چی شد کس دیگه ای حمله ای که از قلم افتاده باشه سراغ نداره؟
یعنی فقط همیناس؟
اینهمه پروفسور PHP اینجا که میگن سابقه کار چی داری یعنی حمله هایی بیشتر از این چنتا رو نمیشناسن؟
البته عمده هاش شاید اینا باشه. اما حدس میزنم حداقل چهار پنج تا حملهء باحال دیگه وجود داشته باشه! شایدم بیشتر.

eshpilen
یک شنبه 21 فروردین 1390, 10:36 صبح
بنام خدا؛ بعلت کمبود در ذخیرهء Karma اقدام به درج روشهای جلوگیری از این حمله ها میکنیم :لبخند:

مورد اول: SQL Injection
این حمله از متداول ترین و خطرناک ترین حمله ها در تاریخ وب میباشد.

روش جلوگیری از SQL Injection خوشبختانه کاملا ساده است.
ما باید مقدارهایی رو که از منابع غیرقابل اعتماد، مثل مقادیر فیلدهای فرمهایی که از سمت کاربران ارسال میشه، دریافت میکنیم، قبل از بکار بردن در کوئری های خودمون توسط تابع mysql_real_escape_string به اصطلاح Escape کنیم (بصورت دقیق، تنها کاراکترهای خاصی رو Escape میکنه).

یک تابع برای این کار بطور مثال که کار بیشتری هم انجام میده:


function quote_smart($value)
{

if(!is_numeric($value)) {
if(get_magic_quotes_gpc()) $value = stripslashes($value);
return "'" .mysql_real_escape_string($value) . "'";
}
else return $value;

}

این تابع رو از منول PHP کپی کردم. چون تابع بی نقص و ردیفی هست!
بجای اینکه تابع mysql_real_escape_string رو سوا بنویسید و بقیهء کد رو هم بریزید توی دل و رودهء برنامه میتونید از این تابع تر و تمیز استفاده کنید که ضمنا رشته های شما رو هم در داخل کوتیشن قرار میده.
اگر دقت کنید اول چک میکنه که مقدار پاس شده عددی هست یا خیر. اگر عدد نباشه یعنی وقتی داخل کوئری بعنوان مقدار یک فیلد درج میشه نیاز به کوتیشن داره و بنابراین این کوتیشن ها رو خودش بصورت خودکار اضافه میکنه و نیازی نیست شما در داخل کوئری یا جای دیگه این کار رو انجام بدید. اگر مقدار پاس شده عدد باشه، یعنی یک رشته مثلا بصورت 1.43، نیاز نه به کوتیشن داره و نه Escape کردن و بنابراین مقدار بدون تغییر برگردونده میشه.
راستی شاید بپرسید خط if(get_magic_quotes_gpc()) $value = stripslashes($value); چیکار میکنه.
خب این magic_quotes_gpc سیستمی در PHP هست که اگر روشن باشه خودش بصورت خودکار ورودی هایی مثل فیلد فرمهای پست شده رو توسط تابع addslashes به اصطلاح Escape میکنه. اما ما میخوایم از تابع ویژهء MySQL یعنی mysql_real_escape_string برای Escape کردن استفاده کنیم. اگر مقادیر قبلا توسط addslashes اسکیپ شده باشن این اسکیپ دوباره باعث اسکیپ مضاعف میشه که مقادیر رو خراب میکنه، بخاطر همین ما با تابع stripslashes اثر addslashes رو از بین میبریم.

یه مثال از روش استفاده:


$username=quote_smart($_POST['username']);
$password=quote_smart($_POST['password']);

$query="select * from `user_accounts` where `username`=$username and `password`=$password";

بنده خیلی وقته کد PHP ننوشتم و اینو بدون تست درج کردم؛ یوقت اگر مشکلی داشت بگید.
نکتهء دیگه اینکه بخاطر امنیت و از نظر اصولی معمولا پسورد رو مستقیما در دیتابیس ذخیره نمیکنن، بلکه هش پسورد رو بجاش ذخیره میکنن (*) و موقعی که میخوان پسورد وارد شده توسط کاربر رو با دیتابیس چک کنن، از پسورد کاربر هش میگیرن که در اینصورت دیگه نیازی به اعمال quote_smart بر روی این هش نیست (چون در خروجی هش کاراکترهای خطرناک نداریم). اما ما اینجا بعنوان مثال و برای درک مطلب و سادگی فرض کردیم که پسورد مستقیما در دیتابیس ذخیره شده.

*: بعنوان یه مطلب که ربط مستقیمی با موضوع نداره ولی مفیده باید عرض کنم که همیشه از هش تولید شده همراه با salt استفاده کنید، نه هش تنها از پسورد.

eshpilen
یک شنبه 21 فروردین 1390, 20:18 عصر
روش جلوگیری از XSS

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

روش اول از طیق ورودیهای کاربر هست. دقیقا مثل SQL Injection در اینجا هم ما از یه تابع مخصوص برای کاری شبیه Escape کردن بعضی کاراکترها استفاده میکنیم. اسم این تابع htmlspecialchars هست. بجز تفاوت در این تابع با SQL Injection، تفاوت دیگر این هست که در SQL Injection ما ورودی کاربر رو موقع درج در دیتابیس Escape میکنیم، اما درمورد جلوگیری از XSS ما موقعی که ورودی کاربر رو در صفحهء وب نمایش میدیم از تابع htmlspecialchars استفاده میکنیم، چون این حمله و تهدیدی نسبت به دیتابیس نیست، بلکه حمله ای به سورس صفحهء HTML خروجی محسوب میشه.
البته چند نکته رو بگم. اول اینکه شما میتونید تابع htmlspecialchars رو موقع درج ورودیهای کاربر در دیتابیس هم اعمال کنید، به این شکل دیگه نیازی ندارید که موقع نمایش این اطلاعات در صفحات سایت تابع htmlspecialchars رو به اونا اعمال کنید، چون اطلاعات از قبل امن سازی شدن، اما بنده شخصا این روش رو ترجیح نمیدم چون اصالت اطلاعات رو حفظ نمیکنه (یعنی معلوم نمیشه شکل اولیهء اطلاعات کاربر دقیقا چی بوده) و ترجیح میدم موقع نمایش اطلاعات در صفحات تابع htmlspecialchars رو اعمال کنم.
دوم اینکه چه درمورد حملهء SQL Injection و چه درمورد حملهء XSS بعضیا ممکنه بجای اعمال این توابع، کلا کاراکترها یا عبارتهایی رو که میتونن مورد سوء استفاده قرار بگیرن از ورودیهای کاربر حذف کنن. این روش هم کار میکنه، اما انعطاف و آزادی برای نرم افزار و کاربران رو پایین میاره و همچنین حفظ اصالت اطلاعات وارد شده توسط کاربر رو به شدت مخدوش میکنه (این میتونه به بعضی مشکلات و اشتباهات برای کاربران هم منجر بشه)، و بنده در این کار ضرورتی هم نمیبینم (*). ضمنا شما بهرصورت حتی اگر این کاراکترها رو حذف کردید، بازم از نظر اصولیش باید توابع mysql_real_escape_string و htmlspecialchars رو در جای همیشگی استفاده کنید تا مثلا اگر تنظیمات سایت تغییر کرد یا در آینده کاراکتر جدیدی به مجموعه کاراکترهای دارای معنای خاص اضافه شد، برنامه بصورت خودکار امن بمونه و وابسته به یادآوری و ویرایش دستی شما نباشه.

خب روش جلوگیری از حملهء XSS در روش اول (ورودیهای کاربر):

اول که شما اطلاعات فرم رو، مثلا کامنتی رو که یک کاربر برای مقاله ای وارد کرده، در دیتابیس وارد میکنید. در این مرحله مسلما برای جلوگیری از SQL Injection باید عمل درج در دیتابیس رو مطابق مطالب قبلی که درمورد جلوگیری از SQL Injection گفته شد انجام بدید. یعنی باید تابع mysql_real_escape_string رو، البته همراه با ریزه کاریهای جانبی ای که داره، به دیتای کامنت کاربر قبل از درج در کوئری اعمال کنید. اما در این مرحله نیازی به اعمال تابع htmlspecialchars بر ورودی های کاربر نیست. هیچوقت ضرورتی نداره تابع htmlspecialchars موقع درج اطلاعات در دیتابیس استفاده بشه، بلکه موقعی که اطلاعات رو از دیتابیس بیرون کشیدیم و خواستیم در صفحه نمایش بدیم باید این تابع رو اعمال کنیم.

این یک نمونهء فرضی و ساده شده از درج اطلاعات وارد شده توسط کاربر در دیتابیس:


$comment=quote_smart($_POST['comment']);
$user=quote_smart($username_or_guest);

$query="insert into `comments` (`user`, `comment`) values ($user, $comment)";

توجه کنید که ما تابع quote_smart رو به نام کاربری هم اعمال کردیم، با اینکه در این مثال نام کاربری از طریق فرم کامنت وارد نشده و از نام از قبل ثبت نام شدهء کاربر لاگین شدهء فعلی یا عبارت «مهمان» استفاده میشه. این بخاطر این هست که نام کاربری هم جزو اطلاعاتی هست که منشاء اولیهء اون بهرحال یک منبع غیرقابل اعتماد، یعنی ورودیهای کاربر بوده و ممکنه شامل کاراکترهای معنادار در MySQL باشه. گرچه این اطلاعات موقع درج در دیتابیس Escape شدن، اما این Escape شدگی فقط موقع ترکیب و تفسیر کوئری کاربرد و وجود داره و بعد از اون اطلاعات بصورت خام اولیه در دیتابیس ذخیره میشن و بنابراین باید بیاد داشته باشیم که وقتی ما اونا رو از دیتابیس بیرون میکشیم بصورت Escape نشده هستن و بنابراین وقتی میخوایم اونا رو دوباره در یک کوئری درج کنیم، باید دوباره اونها رو Escape کنیم.

بعد موقعی که کامنت ها رو از دیتابیس بیرون میکشیم و در صفحه نمایش میدیم:


$query="select `user`, `comment`, `date` from `comments` where `article_no`=$article_no";

$result=mysql_query($query);

if($result) while($row = mysql_fetch_assoc($result)) {
echo '<center>', htmlspecialchars($row['user'], ENT_QUOTES), ' - ', $row['date'], '</center>';
echo '<br />';
echo htmlspecialchars($row['comment'], ENT_QUOTES);
echo '<hr />';
}

دقت کنید که فلگ ENT_QUOTES رو هم در تابع htmlspecialchars بکار ببرید.
توجه کنید که ما علاوه بر کامنت، نام کاربری رو هم موقع نمایش در صفحه از تابع htmlspecialchars عبور دادیم؛ چون ممکنه نام کاربری هم شامل کاراکترهای خاص HTML باشه. حتی اگر سیستم ولیدیشن شما اجازهء ثبت نام کاربر با این کاراکترهای خاص رو نمیده، بازم باید تابع htmlspecialchars رو برای اصولی بودن برنامه و انعطاف لازم بکار ببرید.

*: کسانی که فکر میکنن باید کاراکترها و عبارتهای خطرناک رو بطور کلی حذف کرد و درج اونها در دیتابیس و اجازه دادن به کاربر در تعیین مشخصات و اطلاعات خودش بصورتی که حاوی این کاراکترها و عبارتها باشن اشتباه هست باید به نرم افزارهای معروفی مثل نرم افزار همین فروم (vBulletin) که توسط برنامه نویسان خبره نوشته شده و بصورت گسترده مورد استفاده و هدف مطلوبی برای نفوذگرها هست توجه کنن. بطور مثال در اینجا شاید من نتونم از عبارتی مثل <script>alert('Hi!');</script> بعنوان نام کاربری استفاده کنم، اما در بخشهای دیگر هیچ محدودیتی در این زمینه نیست و مثلا این عبارت همین الان در این پست من درج شد و نمایش داده شد یا میتونم این عبارت رو بعنوان امضای خودم در این فروم قرار بدم (همین الان امتحان کردم). همچنین هر کد و کاراکتر دیگری رو میشه در این فروم درج کرد. پس صرف قبول کردن و درج این کاراکترها و عبارتها در دیتابیس و نمایش اونها هیچ خطری نداره و دلیلی برای ایجاد محدودیت در این زمینه وجود نداره.

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

eshpilen
سه شنبه 23 فروردین 1390, 13:46 عصر
راه دوم برای حمله های XSS، با استفاده از ضعفی به شرح زیر صورت میگیره.

احتمالا شما تاحالا کدی به این شکل نوشتید:


<form action="<?php echo $_SERVER['PHP_SELF']; ?>">

اگر صفحه ای رو که این کد درش هست، بطور مثال صفحهء test.php در ریشهء سایت، با آدرسی مشابه آدرس زیر باز کنید متوجه مشکلی میشید:

http://localhost/test.php/%22%3E%3Cscript%3Ealert%281%29%3C/script%3E%3Cooo%20a=%22

یعنی یک کادر پیام جاوااسکریپت اجرا میشه که نشون میده که تزریق یک اسکریپت در صفحه صورت گرفته.

مشکل از استفاده از PHP_SELF ناشی میشه و البته شما هم حق دارید که از این قضیه اطلاع نداشته باشید، چون مورد عجیبی هست که مورد انتظار کسی نیست. بنده هم کدهایی که تاحالا نوشتم این ضعف رو داشتن!

روش جلوگیری:


<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES); ?>">
دقت کنید که فلگ ENT_QUOTES رو هم در تابع htmlspecialchars بکار ببرید.

البته اگر از SCRIPT_NAME بجای PHP_SELF استفاده میکنید، خوشبختانه این مشکل با SCRIPT_NAME وجود نداره؛ ولی اینو بدونید که متغییر SCRIPT_NAME ممکنه روی بعضی نرم افزارهای سرویس دهندهء وب (وب سرور) تعریف نشده باشه.

eAmin
یک شنبه 28 فروردین 1390, 14:55 عصر
انواع حملاتی که در وب انجام میگیره رو شما میتونید از این منبع (https://www.owasp.org/index.php/Attacks) پیدا کنید.

eshpilen
یک شنبه 28 فروردین 1390, 19:17 عصر
اوه عجب منبع خوبیه!
از اون منابعی هست که باید هر شب یکی دوتا موردش رو خوند تا تموم بشه. منکه از الان شروع کردم.
البته به زبان انگلیسی هست.
واسه همین فکر میکنم اینطور تاپیک ها هم لازم و مفید باشن.
سعی میکنم اگر مورد دیگری در این منبع دیدم که بدرد تاپیک ما میخوره اضافه کنم.
ضمنا باید بگم حمله و ضعف زیاد هست، ولی خیلی از اونا هم خیلی کم در برنامه های عادی وجود دارن، خطرشون کمه، یا روش اجرای عملی اونها خیلی دشوار هست برای حمله کننده.
ما در این تاپیک سعی میکنیم فقط موارد درشت و متداول و خطرناک ترین ها رو مطرح کنیم. مجال هم بیش از این نیست. هرکس بیشتر میخواد همین قبیل منابع رو میتونه بخونه.

i-php-i
یک شنبه 28 فروردین 1390, 19:36 عصر
انواع حملاتی که در وب انجام میگیره رو شما میتونید از این منبع (https://www.owasp.org/index.php/Attacks) پیدا کنید.
یه منبع برای آموزش ذخیره سسشن ها توی دیتا بیس و مقابله با سرقت نشست سراغ ندارید؟

رضا قربانی
یک شنبه 28 فروردین 1390, 21:56 عصر
چند تا هم ما بگیم :

Command Injection
CSRF
UXss

hosseintdk775
یک شنبه 28 فروردین 1390, 22:33 عصر
یه منبع برای آموزش ذخیره سسشن ها توی دیتا بیس و مقابله با سرقت نشست سراغ ندارید؟
بسم الله الرحمن الرحیم
سلام
در این لینک مطلبی در مورد ذخیره سشن در دیتابیس هست:
http://cyberrabbits.net/485/save-session-in-db/

eshpilen
یک شنبه 28 فروردین 1390, 22:46 عصر
چند تا هم ما بگیم :

Command Injection
CSRF
UXss
Command Injection رو شاید بشه اضافه کرد. باید درموردش فکر کنم.
من این مورد رو قبلا دیدم اما اضافه نکردم، چون بنظرم برنامه های کمی هستن که چنین سیستم و کاربردی داشته باشن و درمقابل این حمله آسیب پذیر باشن. باید یه مورد خاصی باشه که ورودی کاربر سر از خط فرمان دربیاره تا این حمله امکان پذیر باشه. نمیخوام تاپیک رو با لیست کردن و توضیح و راه حل تمام حمله های موجود بیخودی حجیم و پیچیده کنم.
قصد این هست که آسیب پذیری هایی رو مطرح کنیم که در بیشتر برنامه ها مطرح هستن.
اون دوتای دیگه هم تکراری هستن و اگر پست اول تاپیک رو نگاه کنید قبلا لیست شدن (UXss هم ظاهرا همون XSS هست).

i-php-i
دوشنبه 29 فروردین 1390, 00:47 صبح
بسم الله الرحمن الرحیم
سلام
در این لینک مطلبی در مورد ذخیره سشن در دیتابیس هست:
http://cyberrabbits.net/485/save-session-in-db/

این مطلب رو قبلا خوندم، منبع دیگه ای سراغ ندارید؟

hosseintdk775
دوشنبه 29 فروردین 1390, 00:53 صبح
اینجا هم یه چیزی هست / البته حدودا مال 7 ساله پیشه:
http://shiflett.org/articles/storing-sessions-in-a-database

tem988
دوشنبه 29 فروردین 1390, 01:23 صبح
بنام خدا؛ بعلت کمبود در ذخیرهء Karma اقدام به درج روشهای جلوگیری از این حمله ها میکنیم :لبخند:

مورد اول: SQL Injection
این حمله از متداول ترین و خطرناک ترین حمله ها در تاریخ وب میباشد.



سلام
این روشی جلوگیری که توضیح دادید
فقط برای ورودی ها استفاده میشه ؟
یعنی حمله فقط از ورودی ها انجام میشه یا جاهای دیگه ای هم هست ؟
بعد اینو برای تمام جاهایی که ورودی میگیریم باید استفاده بشه و اینکه هیچ مشکلی پیش نمیاد ؟
ممنون

i-php-i
دوشنبه 29 فروردین 1390, 01:41 صبح
اینجا هم یه چیزی هست / البته حدودا مال ساله پیشه:
http://shiflett.org/articles/storing-sessions-in-a-database
مطلب جامعی هست اما متاسفانه به زبان فارسی نیست.

اگر مطلبی به زبان فارسی پیدا کردید لطفا اون رو هم برام ارسال کنید.

رضا قربانی
دوشنبه 29 فروردین 1390, 01:54 صبح
مطلب جامعی هست اما متاسفانه به زبان فارسی نیست.

اگر مطلبی به زبان فارسی پیدا کردید لطفا اون رو هم برام ارسال کنید.

دوست من برای پیشرفت به مطالب فارسی تکیه نکن !!!!! تا کی می خوایی منتظر بمونی تا فارسیش بیاد .

وب سایت یک چیز جهانی هست و پس جهانی یاد بگیر ، نه فارسی

i-php-i
دوشنبه 29 فروردین 1390, 02:07 صبح
دوست من برای پیشرفت به مطالب فارسی تکیه نکن !!!!! تا کی می خوایی منتظر بمونی تا فارسیش بیاد .

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

اگر کلاس آماده دارید لطفا برام بفرستید.

eshpilen
دوشنبه 29 فروردین 1390, 12:11 عصر
سلام
این روشی جلوگیری که توضیح دادید
فقط برای ورودی ها استفاده میشه ؟

بطور کلی هر داده ای که از منابع غیرقابل اعتماد یا غیرقابل پیشبینی میاد. میگم غیرپیشبینی میتونه دو معنی داشته باشه، یکی اینکه یه منبع قابل اعتماد ممکنه بعدا غیرقابل اعتماد بشه، و دیگر اینکه ممکنه اصلا قصد حمله نباشه یا انسان مستقیما اون اطلاعات رو تولید نکرده باشه، اما بعلت دارا بودن کاراکترهای خاص در اون اطلاعات باعث خراب شدن کوئری میشه؛ اینجا خطر امنیتی نیست، ولی موجب اخلال در کارکرد برنامه میشه. بنابراین از روش معرفی شده فقط برای جلوگیری از حمله استفاده نمیشه. هرجا منبع غیرقابل اعتماد یا اطلاعات غیرقابل پیشبینی داشتید این روش رو بکار ببرید. اگر جایی مطمئن هستید هیچوقت در اطلاعات کاراکترهای خاص وجود ندارن خب استفاده از این روش ضروری نیست (ولی معمولا ضرری هم نداره). مثلا یه جایی ممکنه مقدارهای ممکن یک فیلد فقط عدد باشه یا یکسری عبارت های ثابت محدود. معمولا این اطلاعات در داخل برنامه تولید میشن یا توسط یک فیلتر از قبل محدود میشن.

یعنی حمله فقط از ورودی ها انجام میشه یا جاهای دیگه ای هم هست ؟۹۰٪ موارد از طریق ورودیهاست. ولی بطور کلی از هر طریقی و از هر منبعی که غیرقابل اعتماد یا غیرقابل پیشبینی باشه باید این روش رو بکار برد. مهم منشاء اولیهء اطلاعات هست، نه اسم و روش هایی که در مسیر از منشاء به برنامه مطرح میشن.
درمورد سایتها و اپلیکیشن های معمولی میشه گفت تقریبا تمام منبع ورود این اطلاعات از طریق ورودیهای کاربران هست. بهرحال جزییات و اون موارد معدود دیگه به هر موردی برمیگرده و مجالش برام نیست همه رو مطرح کنم و شرح بدم.
منظور از ورودی هم فقط ورودی فرم نیست. پارامترهای URL هم جزوش هست. بطور کلی هر اطلاعاتی که از سمت کلاینت میاد. ولی در بیشتر موارد و برنامه ها، اطلاعات فرمها و URL رو در کوئری ها بکار میبریم. ولی مثلا شما داری آمار کاربران رو هم ثبت میکنی و مثلا نوع مرورگر رو هم ثبت میکنی باید User Agent رو هم جزو این اطلاعات حساب کنی چون از سمت کلاینت میاد و قابل دستکاری هست (بطور کلی تمام اطلاعات سمت کلاینت رو میشه جعل کرد). یا حتی اطلاعات یک کوکی رو اگر در کوئری بکار میبرید!


بعد اینو برای تمام جاهایی که ورودی میگیریم باید استفاده بشه و اینکه هیچ مشکلی پیش نمیاد ؟تاجاییکه بنده میدونم نه انشاا... :لبخند:
بطور کلی هم اون تابع رو میشه همیشه و در همه جا برای اطمینان بکار برد. استفاده ازش ضرر خاصی نداره.
البته موارد استثناء همیشه وجود دارن!

tem988
دوشنبه 29 فروردین 1390, 17:48 عصر
سلام
ممنون
این تابعی که نوشتید درست کار نمیکنه
مثلا به مقدار ها کوتیشن میده و خراب میشه
'barnamenevis'
اینطوری
ممنون میشم تابع رو درست کنید

eshpilen
دوشنبه 29 فروردین 1390, 18:56 عصر
تابع درسته. شما موقعی که متغییر رو در کوئری میذارید یا با کاراکتر نقطه الحاق میکنید اطرافش کوتیشن نذارید.
بنده به همین روش بکار بردم و مشکلی نداره.

eshpilen
دوشنبه 29 فروردین 1390, 19:21 عصر
دوستان، با عرض معذرت یه اصلاحیه اعمال شد.
درمورد حملهء XSS و روش جلوگیری از اون با استفاده از تابع htmlspecialchars.
باید به تابع htmlspecialchars یک پارامتر دوم هم بدیم بصورت ENT_QUOTES.
من اول همه جا این تابع رو بدون پارامتر دوم نوشته بودم، اما امروز متوجه شدم که باید ENT_QUOTES رو هم بهش بدیم.
بنابراین همهء مواردی مثل:

htmlspecialchars($var)
باید به:

htmlspecialchars($var, ENT_QUOTES)
تبدیل بشن.

بنده این اصلاحات رو در پستهای قبلیم اعمال کردم.
با عذرخواهی مجدد بابت این اهمال.

eshpilen
سه شنبه 30 فروردین 1390, 20:20 عصر
دوستان یه چیزی بگم درمورد XSS تا مطلب کامل بشه.
XSS و کلا بیشتر مسائل امنیتی گسترده تر از این حرفا هستن که ما اونا رو به چنتا مثال و مورد مطرح شده در این تاپیک محدود بکنیم.
این چنتا موردی هم که بنده گفتم برای توضیح کلی مطلب و چند مورد خیلی متداول و کاربردی بودن که در بیشتر برنامه های بیشتر افراد وجود دارن و نیاز هستن.
بجز اینا بازم هست و حتی مواردی هست که تابع htmlspecialchars به تنهایی کفایت نمیکنه.
مثلا در همین بحث در یک فروم دیگه یکی از دوستان که آدم واردی هست و تاحالا کلی نرم افزارهای خفن مثل ویبالتین رو هک کرده نظیر چنین موردی رو مطرح کرد:

<html>
<body>
<a href="<?php echo htmlspecialchars($_REQUEST['link'], ENT_QUOTES); ?>">hey! click me!</a>
</body>
</html>

در اینجا ما آدرس لینک رو از ورودی کاربر میگیریم و در صفحه درج میکنیم.
حالا بنظر شما آیا این کد امن هست؟
البته خوشبختانه بنده سربلند بیرون آمدم و با اینکه تاحالا چنین کدی نداشتم و یادم نمیاد چیزی درموردش خونده باشم اما تونستم اشکال این روش و راه حل امن رو بگم. و این جز با درک و بینش کامل و عمیق مطلب و دانش لازم ممکن نیست؛ واسه همین میگم باید کامل و عمیق علت و مکانیزم و کارکرد روش همه چیز رو درک کرد چون بتونید حداقل یکسری موارد خاص درشت و چیزهایی رو هم که تاحالا برخورد نکردید پیشبینی کنید (البته این فقط یکی از دلایلش هست).
اول ببینیم ضعف این روش در چیه.
شما اگر این صفحه رو با آدرسی مثل:

http://localhost/test.php?link=javascript:alert%281%29;
(اون کارکترهای <b></b> بین javascript: و alert رو از آدرس حذف کنید. من هرکاری میکنم نرم افزار فروم خودش اضافشون میکنه)

فراخوانی کنید، شاهد تزریق اسکریپت خواهید بود. با وجودی که از تابع htmlspecialchars استفاده کردیم.
البته این مشکل خوشبختانه درمورد PHP_SELF وجود نداره، چون PHP_SELF محتوی آدرس فراخوانی اسکریپت هست که کسی نمیتونه دستکاریش کنه تا با چیزی مثل javascript: شروع بشه.
البته درکنار این تابع و روش، اطمینان حاصل کنید که مشکل رجیسترگلوبالز وجود نداره و رجیسترگلوبالز خاموش هست یا از طریق کدها و روشهای دیگر چک کنید که PHP_SELF دستکاری نشده باشه. بعدا به مورد رجیسترگلوبالز هم خواهیم رسید که روشش خیلی ساده هست. اصلا همینجا یه روش سرراست و کارا رو بهتون میگم! این کد رو در ابتدای هر اسکریپت خودتون بذارید. قبل از هرچیزی دیگری:

if(ini_get('register_globals')) exit("<center><h3>Error: Turn that damned register globals off!</h3></center>");
خب برگردیم به مشکل لینک و javascript:. برای رفع این مشکل باید ورودی کاربر رو چک کنید که فقط با پروتکل های شناخته شده و بی خطری که شما تعیین میکنید شروع شده باشه. مثلا آدرس فقط با http: یا ftp: و امثالهم شروع شده باشه. به این میگن روش لیست سفید که روش سختگیرانه ولی لازم در چنین مواردی هست. در روش لیست سفید تعداد محدودی عبارتهای مجاز رو تعیین میکنیم و هرچیز دیگری بغیر از اونها رد میشه. در روش لیست سیاه (Black list) بعکس تعداد محدودی عبارتهای غیرمجاز رو تعیین میکنیم و هرچیز دیگری بغیر از اونها تایید میشه. لیست سیاه روش آزادتری هست.
اینکه از لیست سفید استفاده میکنیم بخاطر اینه که ممکنه تمام پروتکل ها و URI scheme های خطرناک رو ندونیم یا در آینده URI scheme های جدیدی بوجود بیان که قابل سوء استفاده باشن. ضمنا خوشبختانه این روش مشکل و محدودیت خاصی درمورد چنین چیزهایی مثل درج لینک های کاربران ایجاد نمیکنه چون میشه 99% آدرسهایی رو که کاربران نیاز دارن به این روش تایید کرد. مثلا حتی آدرسهایی مثل لینک فراخوانی یاهومسنجر و غیره رو.

حالا میتونیم با یک سوال ظرافت های این مسائل و بینش لازم رو محک بزنیم:
یکی ممکنه بجای http: رشتهء http رو چک کنه (بدون کالن). آیا بنظر شما این روش بقدر روش قبلی اصولی/امن هست و چرا؟

eshpilen
جمعه 02 اردیبهشت 1390, 19:05 عصر
خب این CSRF یا XSRF رو هم بگم و برم. معلوم نیست بقیه رو دیگه کی تکمیل کنم یا اصلا این کار رو بکنم یا نه. چون کار شخصی دارم و فعلا که وقت ندارم.
البته ممکنه بخاطر کسب مقداری کارمای مثبت، دوباره این تاپیک رو ادامه بدم. خلاصه بستگی به موجودی ذخیرهء کارما هم داره :لبخند:

CSRF چیست؟
فرض کنید کاربری درحال حاضر در سایت شما لاگین هست.
نفوذگر به روشهای مختلف کاری میکنه که درخواستی از جانب اون کاربر به سایت شما برسه. دقیقا درخواستی که موجب عملیات خاصی میشه. مثلا آدرس مخصوص عملیات لاگ آوت ساده ترین و کم خطرترین مورد هست. ولی اعمال پیچیده تر و خطرناک تری میتونن فراخوانی بشن. مثلا فرض کنید فراخوانی آدرس http://yoursite.com/delete_post.php?post=23611 از طرف کاربر موجب خواهد شد که پست شماره 23611 اون کاربر حذف بشه. ساده ترین و ناشیانه ترین روش برای نفوذگر اینه که این لینک رو تحت عنوان دیگری در اختیار کاربر بذاره، مثلا در یک ایمیل یا در یک صفحهء وب خاص، و کاربر بدون اینکه به آدرس حقیقی لینک دقت بکنه روش کلیک کنه. اما این تنها راه نیست، نفوذگر میتونه کاری کنه که حتی کاربران حرفه ای هم نتونن به اجرای این لینک پی ببرن. مثلا میتونه این لینک رو بعنوان آدرس src یک تگ img در سورس صفحه ای پنهان بکنه:

<img src="http://yoursite.com/delete_post.php?id=23611" />
ضمنا نفوذگر میتونه با دادن طول و عرض صفر و/یا دیگر روشهای دیگری که هست وجود این تگ تصویر رو در صفحه از دید کاربر مخفی بکنه.
وقتی کاربر صفحهء محتوی این تگ img رو بازدید میکنه، مرورگر درخواستی رو برای دریافت تصویر تگ مورد نظر به آدرس http://yoursite.com/delete_post.php?id=23611 ارسال میکنه. همراه این درخواست تمام اطلاعات احراز هویت کاربر هم که به سایت شما تعلق دارن، معمولا کوکی سشن یا لاگین سایت شما، ارسال خواهند شد. بنابراین سایت شما کاربر رو احراز هویت کرده و فرمان صادر شده رو که حذف پست شماره 23611 است انجام خواهد داد.
بجز تگ img نفوذگر میتونست از روشهای دیگری مثل فریم های پنهان در صفحات هم استفاده کنه.
توجه داشته باشید که نفوذگر فقط به لینک های مستقیم و متد GET محدود نیست و میتونه بطور مثال یک درخواست از نوع POST رو هم با اطلاعات مورد نظر خودش از طرف قربانی به سایت شما ارسال کنه. بطور مثال با فرمی که در یک فریم پنهان در صفحه ای قرار داره و بصورت خودکار توسط جاوااسکریپت سابمیت میشه.

خب راه حل چیست؟

روشهای مختلفی برای جلوگیری از این حمله اختراع شدن. اما ما یکی از ساده ترین و متداول ترین این روشها رو که بقدر کافی هم امن هست معرفی میکنیم.
این روش بر این مبتنی هست که هر زمان که صفحه ای رو برای کاربر تولید میکنید که شامل لینک یا فرمهایی هست که عملیات مهمی رو انجام میدن که باید در برابر CSRF ازشون محافظت بشه، یک رشتهء یکتا رو هم به ازای هر کاربر/بازدید تولید میکنید و یک نسخه از این رشته رو در سشن یا مکان دیگری که سمت سرور بتونید بهش دسترسی داشته باشید و نفوذگر بهش دسترسی نداشته باشه ذخیره میکنید و یک کپی دیگر از اون رو به لینک ها و فرمهای مورد حفاظت اضافه میکنید. بعد موقعی که درخواستی از طرف کاربر برای لینکها یا فرمهای ذکر شده به سایت شما ارسال شد، چک میکنید که رشتهء یکتا در اون آدرسها و فرمهای POST شده وجود داشته باشه و اون رشته برابر با رشته ای باشه که شما در مثلا سشن اون کاربر ذخیره کردید.
نفوذگر چون اطلاعی از این رشتهء یکتای مربوط به سشن هرکاربر نداره، نمیتونه یک لینک یا فرم جعلی رو با رشتهء یکتای صحیح ایجاد بکنه.

یک مثال کامل از بکارگیری این روش:


<?php

if(ini_get('register_globals'))
exit('register_globals is on! turn it off.');

//> anti-cache headers
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0");
header('Pragma: private');
header("Pragma: no-cache");
//< anti-cache headers

function random_string($length) {

$chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop qrstuvwxyz0123456789';
$random_string='';
for($i=0; $i<$length; $i++) $random_string.=$chars[mt_rand(0, strlen($chars)-1)];

return $random_string;
}

session_start();

if(isset($_GET['action']))
if(
!isset($_GET['csrf_token']) or
!isset($_SESSION['csrf_token']) or
$_GET['csrf_token']!=$_SESSION['csrf_token']
)
exit('Request rejected!');
else
exit('Request accepted.');

if(isset($_POST['command']))
if(
!isset($_POST['csrf_token']) or
!isset($_SESSION['csrf_token']) or
$_POST['csrf_token']!=$_SESSION['csrf_token']
)
exit('Command rejected!');
else
exit('Command accepted.');

$csrf_token=$_SESSION['csrf_token']=random_string(32);
$self_address=htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES);

echo '<center>';

echo "<a href=\"$self_address?action=delete_record&csrf_token=$csrf_token\">", 'Assume that this link performs an important action.</a><br /><br />';

echo 'And an important form:<br /><br />',
"<form action=\"$self_address\" method=\"post\">",
"<input name=\"csrf_token\" type=\"hidden\" value=\"$csrf_token\" />",
'<input name="command" type="text" value="perform that dangerous action." size="40" />',
'<input type="submit" value="Execute" onclick="return confirm(\'Are you sure?\')" />',
'</form>';

echo '</center>';

?>

این مثال شامل یک لینک و یک فرم محافظت شده در برابر CSRF است.
موقعی که شما در صفحهء خود مثال روی لینک کلیک کنید یا فرم رو سابمیت کنید پیام قبول درخواست رو میده، اما بطور مثال آدرس لینک رو کپی کرده و در آدرسبار مرورگر Paste کنید و مقدار csrf_token رو تغییر بدید یا پارامتر csrf_token رو بطور کلی حذف کنید و بعد لینک رو اجرا کنید، پیامی مبنی بر عدم قبول درخواست نمایش داده میشه.
امیدوارم دیگه نیازی به توضیح خط به خط کد نباشه. اگر کسی چیزی رو متوجه نشد بگه تا توضیح بدم.
ضمنا این فقط یه مثال برای نشون دادن کلیت روش بود.

-----

ویرایش: نظر به اینکه سیستم نمایش کد فروم گند میزنه به کدها، یه نسخه از فایل مثال رو ضمیمه میکنم.

alismith
چهارشنبه 24 اسفند 1390, 12:36 عصر
سلام

دوستان برای حفظ امنیت در سرویس هایی که نیاز به عملیات login نیست چه نظری دارید؟

فرض کنید ما سرویسی داریم که یک فرم در اختیار کاربر قرار میده تا در وب سایت یا بلاگش بذاره تا کاربران اون سایت اطلاعاتی رو از طریق این فرمها بفرستند تا در سرور ما که ارائه دهنده این سرویس هست ذخیره بشند

در گام اول مدیر سایت یه بلاگ در سایت ما عضو میشه
در گام دوم بعد از چند مرحله یک اسکریپت که فراخان یک فایل js هست به کاربر داده میشود

فایل js در هرجایی که قرار بگیرد یک فرم با آدرسی مشخص برای ارسال اطلاعات به سرور ما درست می کند و نمایش می دهد

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

روشها:
1- استفاده از یک کلید و رشته یکتا در فرم که هنگام ارسال اطلاعات با مقدار ذخیره شده در سرویس دهنده بررسی بشه، البته این مقدار با هر بار Refresh سایت کابر و فراخوانی دوباره اون فایل js تغییر خواهد کرد ولی باز این روش امنیت کامل رو برقرار نمیکنه، و میشه ارسال های جعلی از این فرم برای حسابی که مدیر سایت در سرویس ما ساخته فرستاد در حالی که این اطلاعات از سایت اصلی کاربر ارسال نشده!
2- آدرس سایت کاربری که از سرویس ما استفاده می کنه (مدیر سایت یا بلاگ) را در مثلا پروفایل کابر به عنوان اطلاعات ضروری ذخیره کنیم تا بعد که فرم با username این کاربر ارسال شد بررسی کنیم که درخواست از سایت مربوطه بوده یا از مکان دیگری به سرور ما ارجاع داده شده، که باز نمیدونم پیاده سازی این روش و حفظ امنیت و کارایی آن تا چه حد ممکن و قابل اعتماد است!

ممنون میشم ایده های خودتون رو مطرح کنید...


با تشکر-موفق باشید

alismith
چهارشنبه 24 اسفند 1390, 21:51 عصر
دوستان کسی ایده ای نداره.......
؟!

habibvafapour
شنبه 07 بهمن 1391, 20:39 عصر
مرسی دوست عزیز عنوان های خوبی بود تا به حال حتی اسم های نوع حمله را نشنیده بودم
تمام عنوان ها رو از نت دانلود کردم و متوجه به تکنیک صحیح شدم
اگر عنوان های دیگری هم هست لطفاا معرفی کنید
آموزش تمامی عنوانها در سایت آشیانه وجود داره
متشکرم

c.c.i.e
جمعه 04 بهمن 1392, 21:22 عصر
سلام.
با بستن browser و باز کردن آن چه تغییری در Session identifier ایجاد می شود؟
آیا session fixation با متود POST امکان پذیر هست؟ چطور؟

متشکرم.

eshpilen
یک شنبه 06 بهمن 1392, 08:44 صبح
با بستن browser و باز کردن آن چه تغییری در Session identifier ایجاد می شود؟
کوکی سشن و در نتیجه خود سشن حداکثر طول عمرش تا زمان باز بودن مرورگر است. بنابراین با بسته شدن مرورگر، سشن کاربر از بین میره و وقتی دوباره باز کنه سشن جدیدی براش ساخته میشه که Session identifier جدیدی داره. بهرحال کاربر اگر قبلا لاگین بوده، با بستن مرورگر از لاگین خارج شده و نیاز داره تا مجددا لاگین کنه.
خود کاربر به Session identifier قدیمی دسترسی نداره و سشن قدیمی براش بدون کاربرد شده در این حالت، اما اگر Session identifier قدیمی توسط هکر سرقت شده باشه، فکر میکنم میتونه همچنان ازش استفاده کنه.

اما اگر تنظیمات طول عمر کوکی سشن رو روی این بذاریم که با بسته شدن مرورگر، کوکی از بین نره، اونوقت سشن قدیمی سرجاش میمونه (تا وقتی که پارامترهای دیگر باعث منقضی شدنش نشده باشن)، و Session identifier هم عوض نمیشه.

ضمنا از قرار دادن Session identifier در URL هم باید حتی الامکان خودداری بشه و فقط از کوکی استفاده بشه به دلایل امنیتی.
یکسری تنظیمات امنیتی برای سشن:


ini_set('session.use_cookies', '1');
ini_set('session.use_only_cookies', '1');
ini_set("session.cookie_httponly", 1);
ini_set("session.use_trans_sid", 0);


آیا session fixation با متود POST امکان پذیر هست؟ چطور؟
تاحالا یادم نمیاد تحقیق و تست خاصی روش کرده باشم، و متاسفانه الان هم وقتش رو ندارم، ولی فکر کنم میشه (حداقل در بعضی موارد).

c.c.i.e
یک شنبه 06 بهمن 1392, 18:56 عصر
ولی فکر کنم میشه (حداقل در بعضی موارد).

اگه ممکنه درباره موارد خاص یکم توضیح بدین.
ممنون بخاطر لطفتون.

eshpilen
دوشنبه 07 بهمن 1392, 08:38 صبح
خب هر سایتی میتونه یک فرمی رو حالا چه بصورت خودکار توسط جاوااسکریپت و چه بصورت دستی توسط خود کاربر به سایت دیگری سابمیت کنه.
حالا اگر اون فرم سایت مقصد محافظت در برابر CSRF نداشته باشه، اون سابمیت اجرا میشه.
ولی یه مشکل دیگر هم در قدم دوم هست و اون اینکه چطور session id مورد نظر توسط هکر ست بشه.
هکر یا باید بتونه کوکی سشن رو ست کنه، که چون مال دامین دیگری هست نمیشه مگر با استفاده از باگ و حفرهء دیگری در مرورگر یا سایت مورد نظر، یا اینکه اگر بشه از طریق یک فیلد پنهان در فرم (دقیقا یادم نیست چنین روشی هم میشه یا نه)، که اینم باوجود session.use_only_cookies قاعدتا نباید ممکن باشه.

حالا شما چکار داری با این مسئله؟
تمام اقدامات امنیتی رو همیشه رعایت کن.
محافظت در برابر CSRF هم که بخاطر انواع حمله های دیگر هم هست.

peymang
جمعه 12 اردیبهشت 1393, 18:13 عصر
در مورد جلوگیری از sql injection بهترین راه برای جلوگیری از اون
بایند کردن ورودی ها و بعد اجرای کوئری هست
که در اینجا (http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)خیلی کامل بحث شده ( برای PHP)
فرقی نمی کنه در پی اچ پی یا asp.net یا ....

البته احتمالا همه ی دوستان می دونند

و برای مواردی هم نیاز به چک کردن ورودی هایی مانند اسم جدول یا بانک و .... هست می تونیم با استفاده از عبارات منظم (regular expression ) لیست کاراکتر های مجاز رو بررسی کنیم و دیگه نیازی نیست که کاراکتر های خطرناک رو لیست کنیم!
البته عبارات منظم یکمی کند هستن ولی برای عملیاتی مانند ایجاد جدول و بانک ها که بیشتر اوقات یک بار در هنگام نصب اتفاق می افته مشکلی ایجاد نمی کنه ( فکر کنم :لبخندساده:)

و همان طور که در بالا گفته شد برای اجرای کوئری های select , update , insert , delete هم از بایند کردن استفاده می کنیم
مزیت هاش:
که سرعت این روش حتی بیشتر از ایجاد یک کوئری به صورت دستی هست! (داخل یه سایت خوندم ولی نمی دونم کدوم یکی :لبخندساده: )
خوب دیگه sql injection ی در کار نیست
و برنامه خواناتره

mtnam1372
جمعه 12 اردیبهشت 1393, 18:46 عصر
همچین تایپکی در تالار های اشیانه و دیگر تالار های هک وجود دارد به نظر کار عبث و بیهوده ایست