PDA

View Full Version : روش جلوگیری از حملهء CSRF



eshpilen
شنبه 27 فروردین 1390, 22:24 عصر
میخوام یه توضیح و راه حل عمومی ای رو برای جلوگیری از این حمله به زودی در تاپیک انواع حمله های نفوذ و سوءاستفاده از صفحات وب (http://barnamenevis.org/showthread.php?281805) قرار بدم. اما فعلا دارم راههای مختلف رو بررسی میکنم تا مطمئن بشم و ببینیم کسی نظر و راه دیگری نداره یا ایرادی به روش مورد نظر ما وارد نمیکنه.

خب برای جلوگیری CSRF ظاهرا یک راه سرراست و کارا اینه که یک مقدار خاص نشست هر کاربر رو در URL های مورد حفاظت و در فیلد Hidden در فرمهای مورد حفاظت قرار بدیم (و طبیعتا موقع دریافت درخواست ها چک کنیم).
یه نگاهی به آدرس لینک خروج در گوشهء سمت چپ بالای همین صفحه بکنید! آدرسش چنین چیزی هست:

http://barnamenevis.org/login.php?do=logout&logouthash=1302978242-bb87***************************3fcbe
البته اون ستاره ها رو من خودم برای احتیاط جایگزین بقیهء کاراکترهای رشته کردم و بجاش یکسری کاراکترهای ظاهرا رندوم بود که در هر بار رفرش صفحه هم عوض میشن.
فکر میکنم متغییر logouthash در اینجا برای همین کار هست. یعنی برای جلوگیری از CSRF.
البته لاگ آوت کردن از یک سایت چیز چندان مهمی نیست، ولی احتمالا بطور کلی تمام URL ها و فرمهای نرم افزار این فروم به این روش در برابر CSRF محافظت میشن. الان بنده رشتهء مربوطه رو در سورس صفحه جستجو کردم و در لینک ها و فرمهای مختلفی وجود داره.

خب کسی نظری نداره؟
من فکر میکنم این راه خوبیه که در عموم موارد میتونه بکار بره. نیازی به جاوااسکریپت هم نداره.

i-php-i
یک شنبه 28 فروردین 1390, 01:14 صبح
فکر کنم بهترین راه حل همونی هست که خودتون گفتید.


خب برای جلوگیری CSRF ظاهرا یک راه سرراست و کارا اینه که یک مقدار خاص نشست هر کاربر رو در URL های مورد حفاظت و در فیلد Hidden در فرمهای مورد حفاظت قرار بدیم (و طبیعتا موقع دریافت درخواست ها چک کنیم).

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

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

eshpilen
یک شنبه 28 فروردین 1390, 08:09 صبح
فکر کنم بهترین راه حل همونی هست که خودتون گفتید.

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

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

eshpilen
یک شنبه 28 فروردین 1390, 13:02 عصر
دو سوال بعدی پیش میاد:

۱- کلید هش رو چطور تولید کنیم؟
من فکر میکنم استفاده از یک رشتهء رندوم مناسب باشه. البته میتونیم مثل مثالی که آوردم اولش یک timestamp هم اضافه کنیم (البته من نمیدونم چقدر مهمه و چرا). ظاهر ویبالیتن این timestamp رو بصورت یک رشتهء مجزا در ابتدا داره، اما MyBB به اون شکل آشکار نداره اما شاید در تولید هش استفاده میشه. و اصلا این هش چطور تولید میشه؟ آیا از توابع هش ای مثل MD5 استفاده میکنه و چرا؟

۲- این کلید هش رو در کجا نگهداری کنیم که بعد بتونیم با کلید هش URL ها و فرمهای ارسالی مطابقت بدیم؟
خب طبیعتا آدم اول سشن به ذهنش میرسه.
البته در کوکی هم میشه ذخیره کرد.

mtchabok
دوشنبه 29 فروردین 1390, 10:06 صبح
من خودمم برای امنیتی بیشتر فرمهام از رشته های رندم استفاده میکنم و در سشن قرار میدم .
البته اگه در کوکی قرار نگیره بهتره چونکه کوکی هم برای کاربران قابل دسترس و قابل تغییر توسط اونها هس .
در مورد هش هم من خودم از یه رشته ثابت که در تنظیمات سایت قرار میدم + microtime + ip + یه رشته رندم . ایجاد می کنم و تا الان از md5 + md5 استفاده میکردم ولی دارم سعی میکنم که از توابع دیگه هش استفاده کنم ... چونکه یه سایتی رو دیدم که رشته های هش شده توسط md5 رو به سادگی در مدت زمان 1 ثانیه به رشته اصلیش برمیگردوند واسه همین جز برنامه کاریم قرار دادم تا این روش کد کردنم رو تغییر بدم .

eshpilen
دوشنبه 29 فروردین 1390, 15:08 عصر
البته اگه در کوکی قرار نگیره بهتره چونکه کوکی هم برای کاربران قابل دسترس و قابل تغییر توسط اونها هساین اطلاعات بهرصورت در URL ها و فرمهای صفحه کاملا مشهود و در دسترس هستن. بنابراین از این نظر فرقی نمیکنه در کوکی ذخیره کنید یا در سشن.

تا الان از md5 + md5 استفاده میکردم
اصلا چرا از یک تابع هش استفاده میکنید؟

colors
پنج شنبه 04 آبان 1391, 21:53 عصر
کسی راه حلی نداره؟ میگم چطوره تو دیتابایس ذخیره کنیم ها؟




البته اگه در کوکی قرار نگیره بهتره چونکه کوکی هم برای کاربران قابل دسترس و قابل تغییر توسط اونها هس

این اطلاعات بهرصورت در URL ها و فرمهای صفحه کاملا مشهود و در دسترس هستن. بنابراین از این نظر فرقی نمیکنه در کوکی ذخیره کنید یا در سشن.


چه رابطی داره! کاربر که قرار نیست خودشو هک کنه!

djsaeedkhan
شنبه 06 آبان 1391, 00:39 صبح
سلام
به نظر من بهترین و راحت ترین کار اینه که یه مقدار رو به همراه زمان بصورت کد امنیتی در بیاریم و بعد در فیلد هیدن قرار بدیم. بعد از ارسال فرم در فرم نتیجه اونو بررسی کنیم. اگر زمان برای 5 دقیقه پیش بود درج کنیم و در غیر این صورت درج نکنه.
من تو دات نت هم دیدم اینجوری کار میکنه

colors
شنبه 06 آبان 1391, 11:31 صبح
سلام
به نظر من بهترین و راحت ترین کار اینه که یه مقدار رو به همراه زمان بصورت کد امنیتی در بیاریم و بعد در فیلد هیدن قرار بدیم. بعد از ارسال فرم در فرم نتیجه اونو بررسی کنیم. اگر زمان برای 5 دقیقه پیش بود درج کنیم و در غیر این صورت درج نکنه.
من تو دات نت هم دیدم اینجوری کار میکنه

خب CSRF فقط برای فرم نیست که! برای لینکها چکار کنیم؟

eshpilen
یک شنبه 07 آبان 1391, 12:53 عصر
حمله CSRF هم با درخواستهای GET هم با درخواستهای POST امکان پذیره.
روش جلوگیری هم درج توکن در هردوی فرم ها و لینک ها است (البته طبیعتا فرم ها و لینک هایی که سبب انجام عمل حائز اهمیتی از جانب کاربری که در سایت لاگین هست میشن - برای تمام فرم ها و لینک ها وجود توکن معمولا ضرورت نداره).
مثلا این یک نمونه لینک لاگ آوت در پروژهء بنده: http://localhost/reg8log/logout.php?antixsrf_token=5p0HwSSXUPlMuRaGO2h8Xx

اینم قطعه کدی در پروژهء بنده که موجود بودن و مطابقت داشتن توکن رو چک میکنه:


if(!empty($_POST)) {
if(!isset($_COOKIE['reg8log_antixsrf_token'], $_POST['antixsrf_token']) or $_COOKIE['reg8log_antixsrf_token']!==$_POST['antixsrf_token']) {
$failure_msg="<h3>XSRF prevention mechanism triggered!</h3>";
$no_specialchars=true;
require $index_dir.'include/page/page_failure.php';
exit;
}
}
else if(!isset($_COOKIE['reg8log_antixsrf_token'], $_GET['antixsrf_token']) or $_COOKIE['reg8log_antixsrf_token']!==$_GET['antixsrf_token']) {
$failure_msg="<h3>XSRF prevention mechanism triggered!</h3>";
$no_specialchars=true;
require $index_dir.'include/page/page_failure.php';
exit;
}

colors
یک شنبه 07 آبان 1391, 14:37 عصر
حمله CSRF هم با درخواستهای GET هم با درخواستهای POST امکان پذیره.
روش جلوگیری هم درج توکن در هردوی فرم ها و لینک ها است


بله این رو تو پستهای بالای و چند تایپک دیگه مطرح کرده بودین. سوالم این بود که بلاخره به نظر شما اون توکن رو در سمت سرور، کجا ذخیره کنیم؟ داخل سشن؟ کوکی؟ دیتابایس چطوره؟

colors
یک شنبه 07 آبان 1391, 14:39 عصر
حمله CSRF هم با درخواستهای GET هم با درخواستهای POST امکان پذیره.
روش جلوگیری هم درج توکن در هردوی فرم ها و لینک ها است


بله این رو تو پستهای بالای و چند تایپک دیگه مطرح کرده بودین. سوالم این بود که بلاخره به نظر شما اون توکن رو در سمت سرور، کجا ذخیره کنیم؟ داخل سشن؟ کوکی؟ دیتابایس چطوره؟

mtchabok
دوشنبه 08 آبان 1391, 15:57 عصر
سلام
بهترین راه حل این هست که توکن رو در سشن ذخیره کنید البته براساس فرم مربوطه باید بازخوانی بشه تا اگه کاربر در چند فرم همزمان در حال کار بود در اطلاعات توکن تداخلی بوجود نیاد .
اگه در کوکی ذخیره کنید خوب هکر به سادگی میتونه خودش اینو تولید کنه ولی در سشن اینگونه نیست و فقط برنامه نویس اینکارو انجام میده .

eshpilen
سه شنبه 09 آبان 1391, 08:15 صبح
من در کوکی ذخیره کردم. چون این ساده ترین و سریعترین راه بود.
ولی خب اون روش سشن و یک توکن به ازای هر فرم و حتی تغییر توکن در فواصل زمانی، اینا همه میتونن به امنیت اضافه کنن.
شاید بعدا که فرصت کردم این روشها رو روی پروژم استفاده کنم.
بهرصورت یک کوکی ساده ثابت هم در حد Basic امنیت میده. چون تا وقتی هکر نتونه به طریقی کوکی کاربر رو بخونه (معمولا با استفاده از باگهای مرورگرها یا حفره های XSS که در بخشهای دیگر برنامه وجود داشته باشن) نمیتونه کاری بکنه.

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