آموزش رفع باگ CSRF در PHP
سلام
باگ CSRF یکی از معمول ترین باگ هایی هست که هر اسکریپتی میتونه در ابتدا داشته، که این باگ در اسکریپت های آماده نظیر وردپرس، جوملا و … رفع شده است ولی اگر برنامه نویس PHP هستید و شخصا دارید اسکریپتی رو می نویسید باید این رو بدونید که فرم های شما باگ CSRF دارند! در این مقاله نگاهی کوتاه به این باگ و سپس چگونگی رفع این باگ را شرح میدهیم، در ادامه همراه بپرسم باشید.
باگ CSRF چیست؟
مخفف Cross-Site Request Forgeries است و جزو باگ های خطرناک به حساب میاد، این باگ معمولا در فرم هایی که ساختار ثابتی دارند به وجود میاد و همچنین فرم هایی که موقع ارسال اطلاعات پردازش خاصی انجام نمیدن؛ و منظور از تغییر ساختار ظاهری فرم نیست بلکه ساختار درونی فرم است که در ادامه بهش می پردازیم.
فرض میکنیم در سایت یک فرم تماس با ما به شکل زیر داریم:
فرم هایی که ایجاد میکنیم معمولا به این شکل هستند، که چند تا فیلد داریم و توسط متد POST یا GET فرم ها رو به مقصد ارسال میکنیم و پردازش ها رو روش انجام میدیم، این فرم از نظر ساختار(که بالاتر گفتم) ثابت هست، یعنی چی؟ یعنی اینکه ما هر بار که فرم رو رفرش میکنیم اطلاعاتی به فرم اضافه نمیشه، باز همین فیلد ها هستند که کاربر تکمیل میکنه و ارسال میکنه و تو پایگاه داده ذخیره میشه.
CSRF چگونه عمل میکند؟
خب ما تا الان یک فرم ساختیم که به باگ CSRF مجهز هست(از این بابت که ساختار فرم ثابت هست، در بخش بعدی بیشتر توضیح میدم)، فرض میکنیم فرم رو تو سایت قرار دادیم و action فرم به صفحه زیر است:
۱ |
https://beporsam.ir/submitForm.php |
حالا برای اینکه ببنید CSRF چگونه کار میکند کافیست یک فایل با پسوند html تو سیستم بسازید، و دقیقا کدهای داخل تگ Form را داخلش قرار بدید و ذخیره کنید، و صفحه ای که درست کردید رو تو مرورگر اجرا کنید، حالا هر چی که فیلدها رو تکمیل کنید و ارسال بزنید، می بینید که ارسال میشه و ثبت میشه.
فکر کنم تا الان فهمیدید که باگ CSRF چه جوری عمل میکنه، درسته؟ اگه هنوز متوجه نشدید، ویدئوی کوتاه زیر رو بببینید:
این فقط یک مثال ساده بود، فرض کنید اطلاعات فرم تماس با ما در دیتابیس ذخیره بشه، اون موقع هکر چه حجم داده ای میتونه به سایت شما بفرسته، یا اینکه این باگ در فرم ورود به پنل مدیریت سایت یا پنل کاربری باشه.
رفع باگ CSRF چگونه است؟
روش های زیادی برای رفع این باگ خطرناک وجود داره که در ادام به ۳ تا اشاره میکنیم
- شرط بزارید که ایا فرم ارسال شود یا خیر؟
- استفاده از Captcha(تصویر امنیتی)
- استفاده از Token های تصادفی
که استفاده از دو روش Token و Captcha با هم خوبه، ولی استفاده از Token به تنهایی هم میتونه شما را در برابر این باگ محافظت کنه، منظور از Token یک شناسه تصادفی است که با هر بار Refresh صفحه مقدار جدیدی میگیره و در Session(سیشن) ذخیره میشه و ما این مقدار رو همراه با فرم ارسال میکنیم، و قبل از ارسال اطلاعات بررسی میکنیم که آیا Token فرستاده شده با Token که در سیشن ذخیره شده برابر است یا نه، اگر برابر بود که اطلاعات رو ارسال، اگر هم نبود که از ارسال اطلاعات جلوگیری میکنیم.
آموزش:
- برای کار با سیشن ها قبل از هر کاری باید Session را Start کنیم.
۱ |
session_start(); |
- سپس یک شناسه ی تصادفی ایجاد میکنیم و در داخل متغیری به نام token$ ذخیره میکنیم.
۱ |
$token = md5(uniqid(rand(), TRUE)); |
شناسه تولید شده باید منحصر به فرد باشد تا توسط هکر قابل حدس زدن نباشد.
- یک Session میسازیم و مقدار token$ را داخلش ذخیره میکنیم.
۱ |
$_SESSION['csrf_token'] = $token; |
یک Session به نام csrf_token ایجاد کردیم و مقدار متغیر token$ را در این سیشن ذخیره کردیم.
سیشن چیست؟ سیشن متغیرهای سراسری هستند که وقتی تعریف میکنیم تو کل برنامه میتونیم ازشون استفاده کنیم، و هم میتوانیم با دستور session_destroy() سیشن را حذف و هم پس از بستن مرورگر سیشن حذف میشود.
- حالا باید در form مقدار سیشن را قرار بدیم تا با ارسال فرم، سیشن هم ارسال بشه، برای اینکار یک input از نوع hidden میسازیم.
۱ |
<input type="hidden" name="csrf_token" value="<?php echo $token; ?>"> |
یک input از نوع hidden ایجاد کردیم، چون قرار نیست کاربر input رو ببینه و مقدار token$ را در value چاپ میکنیم، تا با ارسال فرم Token هم ارسال بشه.
- مرحله بعد باید قبل از ارسال اطلاعات بررسی کنیم که آیا توکن فرستاده شده با توکن ذخیره شده در سیشن برابر است یا خیر.
۱ ۲ ۳ ۴ ۵ |
if($_SESSION['csrf_token'] === $_POST['csrf_token']){ // True }else{ //False } |
اگر صحیح بود اجازه ارسال اطلاعات را میدیم(True) اگر غلط بود از ارسال اطلاعات جلوگیری میکنیم.
- و در مرحله ی آخر از فرم در بخش پنل کاربری یا پنل ادمین استفاده میکنید، همراه با خروج کاربر مقدار Session را خالی کنید.
۱ |
unset($_SESSION['csrf_token']); |
در ادامه ویدئوی قبلی میریم تا فرمی که ساختیم رو ایمن کنیم:
در پایان سورس آموزش رو میتونید دانلود کنید، همراه ما باشید با دیگر آموزش ها …
موفق باشید.
ارسال نظر
شما باید وارد شوید یا عضو شوید تا بتوانید نظر ارسال کنید