فریمورک محبوب لاراول، در عین سادگی دارای نکات و جزئیات فراوانی است که یادگیری آنها نیازمند دقت و صرف زمان مناسب میباشد. یکی از نکات مهم در بحث امنیت، حفاظت CSRF در لاراول میباشد که از وب اپلیکیشنها در برابر حملات Cross-Site Request Forgery محافظت میکند. شناخت این نوع از حملات و راههای مقابله با آنها یکی از موارد مهمی است که هر برنامه نویس لاراول باید از آن آگاهی داشته باشد.
حمله CSRF چیست؟
CSRF مخفف Cross-Site Request Forgery میباشد که به معنای جعل درخواست از طریق سایت است. CSRF یک حفره امنیتی در وب است که به مهاجم اجازه میدهد تا کاربران را وادار به انجام کارهایی کند که قصد انجام آنها را ندارند. این حمله به مهاجم این اختیار را میدهد تا سیاستهایی که برای جلوگیری از دخالت وب سایتهای مختلف در کار یکدیگر طراحی شدهاند را دور بزند.
به عنوان مثال فرض کنید، کاربران سایت google.com با وارد کردن آدرس google.com/logout کوکی مرورگرشان حذف میشود و در نتیجه logout میشوند. حال اگر یکی از کاربران در یک سایت دیگر (مثلاً در یک انجمن شلوغ) تصویری با تگ img زیر ارسال کند و افراد دیگر حاضر در آن انجمن این تصویر را مشاهده کنند، از طرف مرورگرشان درخواستی به سایت گوگل ارسال میشود و موجب میشود تا همه کسانی که آن تصویر را دیدهاند از اکانت گوگلشان بیرون انداخته شوند.
<img src="http://www.google.com/logout/" alt="" />
البته این مثال یک نمونه ساده و غیر خطرناک بود. حالتهای بسیار خطرناک دیگری نیز وجود دارد.
CSRF چگونه کار میکند؟
CSRF باعث میشود برنامههای وب نتوانند بین درخواستهای معتبر و درخواستهای جعلی کنترل شده توسط مهاجم تمایز قائل شوند. روشهای زیادی وجود دارد که یک مهاجم سعی میکند از حفره امنیتی CSRF استفاده کند. در ادامه برای درک بهتر این نوع حملات، با ذکر یک مثال به توصیف چگونگی حملات CSRF در لاراول میپردازیم.
فرض کنید، شخصی به نام باب یک حساب بانکی آنلاین در سایت samplebank.com دارد. او مرتباً برای انجام معاملات خود از این سایت بازدید میکند. باب اطلاعی ندارد که samplebank.com در برابر حملات CSRF آسیب پذیر است. در همین حال یک مهاجم قصد دارد با استفاده از این حفرهی امنیتی ۵۰۰۰ دلار از حساب باب به حساب دیگر منتقل کند.
برای انجام موفقیت آمیز این حمله:
- مهاجم باید یک URL بهرهبرداری ایجاد کند.
- مهاجم باید باب را فریب دهد تا روی URL بهرهبرداری کلیک کند.
- برای لاگین کردن و کار با حساب، باب نیاز به یک session فعال در سایت samplebank.com دارد.
در ادامه، باب برای انتقال پول در سایت بانک، یک درخواست با روش GET ارسال میکند. به این ترتیب درخواست انتقال ۵۰۰ دلار به حساب دیگر (با شماره حساب ۲۱۳۳۶۷ ) ممکن است به شکل زیر باشد:
GET https://samplebank.com/onlinebanking/transfer?amount=500&accountNumber=213367
همانطور که قبلا گفتیم، یک مهاجم برای انجام موفق حمله CSRF باید یک url مخرب ایجاد کند تا ۵۰۰۰ دلار به حساب ۴۲۵۶۵۴ منتقل کند.
https://samplebank.com/onlinebanking/transfer?amount=5000&accountNumber=425654
حالتی را در نظر بگیرید که در آن از تگ img استفاده میشود. در این حالت، مهاجم ایمیلی حاوی یک تصویر به باب ارسال میکند. برنامهی مرورگر باب با دریافت آن، url موجود در تگ img را به صورت خودکار باز میکند. در نتیجه بدون دخالت باب، درخواست ناخواسته به سایت بانک ارسال میشود. اگر باب در سایت samplebank.com یک session فعال داشته باشد. سایت، این url را به عنوان درخواست انتقال پول از طرف باب شناسایی میکند و سپس مبلغ مورد نظر به حساب مشخص شده توسط مهاجم منتقل میشود.
البته توجه داشته باشید که برای انجام موفق حمله CSRF برخی محدودیتها وجود دارد. از جمله:
- این حمله تنها در صورتی موفقیت آمیز خواهد بود که کاربر دارای یک session فعال در یک وب سایت آسیب پذیر باشد.
- مهاجم باید یک url معتبر پیدا کند تا با سوءنیت آن را دستکاری کند. url مورد نظر لازم است باعث تغییر وضعیت در سایت هدف شود.
- در آخر مهاجم باید مقادیر مناسب پارامترهای url را پیدا کند. در غیر این صورت وب سایت هدف ممکن است درخواست مخرب را رد کند.
حفاظت CSRF یا CSRF Protection چیست؟
لاراول یک راهکار آسان به نام CSRF Protection برای محافظت در برابر حملات CSRF ارائه داده است. حفاظت CSRF در لاراول به این صورت است که به ازای هر کاربر فعال در اپلیکیشن، برنامه یک توکن CSRF تولید میکند. این توکن برای تایید این است که آیا درخواستی که ارسال میشود از سمت یک شخص واقعی است یا خیر.
هر وقت شما یک فرم HTML که با تگ <form> شناخته میشود را در صفحه ایجاد میکنید، حتماً باید توکن CSRF را در داخل آن قرار دهید، تا حفاظت CSRF در لاراول بتواند درخواست را تایید کند. در صورتی که این کار را انجام ندهید درخواست شما faild یا ریجکت میشود. برای انجام این کار تنها کافی است عبارت CSRF@ را در داخل تگ فرم خود قرار دهید. مانند کد زیر:
<form method="POST" action="/profile">
@csrf
...
</form>
میدلور VerifyCsrfToken که در گروه میدلورهای وب قرار دارد، به طور خودکار تایید میکند که توکن موجود در درخواست با توکن ذخیره شده در session مطابقت دارد یا خیر.
جلوگیری از حملات CSRF در PHP
در ادامه به معرفی چند روش برای جلوگیری از اینگونه آسیبها در php میپردازیم.
جلوگیری از حملات CSRF در لاراول با بررسی header صفحات
این کار میتواند به جلوگیری از حملات CSRF کمک کند. اگر درخواست از دامنه دیگری ارسال شده باشد، این درخواست حتماً جعلی است بنابراین باید مسدود شود.
جلوگیری از حملات CSRF در لاراول با تایید captcha در فرمها
تایید captcha یک روش خوب برای جلوگیری از حملات CSRF به فرمها میباشد. در ابتدا، فرآیند تایید کپچا برای جلوگیری از رباتها ایجاد شد. اما علاوه بر آن، میتوان از کپچا برای جلوگیری از حملات CSRF استفاده کرد. از آنجا که کپچا به صورت تصادفی در سمت کاربر ایجاد میشود، مهاجم نمیتواند الگو را حدس بزند.
بنابراین او هرگز قادر نخواهد بود که کپچای صحیح را با درخواست جعلی ارسال کند و همه درخواستهای جعلی مسدود میشوند. توجه داشته باشید که این روش زیاد کاربر پسند نیست. اکثر کاربران دوست ندارد که تعداد زیادی کپچا را در وب سایت پر کنند بنابراین باید تلاش کنیم تا راههای جلوگیری از CSRF را بدون اضافه کردن بار اضافی بر روی کاربران پیدا کنیم.
جلوگیری از حملات در لاراول با استفاده از توکنها
استفاده از توکنها ایمنترین روش برای جلوگیری از حملات CSRF میباشد. برخلاف روش کپچا، این روش هیچ ارتباطی با کاربران ندارد، بنابراین کاربران هرگز نمیدانند که چیزی برای محافظت از آنها اضافه شده است. در این روش، وب سایت یک توکن تصادفی در هر فرم به عنوان یک مقدار پنهان ایجاد میکند. این توکن با session کاربران مرتبط است. پس از ارسال فرم، وب سایت بررسی میکند که آیا توکن تصادفی از طریق درخواست ارائه میشود یا خیر. در صورت مثبت بودن جواب، درست بودن توکن بررسی میشود.
با استفاده از این روش، توسعه دهندگان میتوانند به راحتی تشخیص دهند که آیا درخواست توسط مهاجم انجام شده است یا خیر. مثلا:
[html]</pre>
<form action="accountdelete.php" method="post"><input type="hidden" name="CSRFToken" value="OWY4NmQdwODE4hODRjN2DQ2NTJlhMmZlYWEwYzU1KYWQwMTVhM2JmLNGYxYjJiMGI4jTZDE1ZDZjMTViMGYwMGEwOA==" />
…</form>
<pre>
[/html]
CSRF token چیست؟
توکن CSRF یک مقدار منحصر به فرد، مخفی و غیر قابل پیش بینی است که توسط برنامه در سمت سرور تولید و در هر درخواست کاربر گنجانده میشود. هنگامی که درخواست کاربر ارائه میشود، برنامه در سمت سرور تایید میکند که این درخواست شامل توکن مورد انتظار است، در صورت عدم وجود و یا نامعتبر بودن آن، درخواست توسط برنامه رد میشود. میزان تأثیر توکن به روش تولید آن بستگی دارد، بنابراین همیشه سعی کنید توکن را به روشی تولید کنید که غیر قابل پیش بینی باشد.
برای تولید توکن میتوانید از کد زیر استفاده کنید.
$randomtoken = md5(uniqid(rand(), true));
یا
$randomtoken = base64_encode( openssl_random_pseudo_bytes(32));
پس از ورود کاربر و ایجاد session لاگین، randomgtoken$ را ایجاد کنید و آن را به session اضافه کنید.
$_SESSION[‘csrfToken’]=$randomtoken
همچنین برای هر فرم، تگ مخفی زیر را اضافه کنید.
<input type=’hidden’ name=’csrfToken’ value='<?php echo($_SESSION[‘csrfTOken’]) ?>’ />
توکن CSRF برای هر session منحصر به فرد است. در هر session جدید دوباره توکن ایجاد میشود. همچنین شما میتوانید از یک توکن واحد برای همه فرمها استفاده کنید، اما استفاده از توکنهای متفاوت، ایمنتر میباشد. در ادامه به معرفی چند کلاس و کتابخانه اپن سورس php برای محافظت در برابر حملات CSRF میپردازیم. این موارد عبارتند از:
محافظت در برابر حملات CSRF با استفاده از کلاس NoCSRF
NoCSRF یک کلاسهای ساده و ضد حمله CSRF است که کار تولید توکن را انجام میدهد. همچنین شما میتوانید برای یادگیری نحوی پیاده سازی این کلاس در وب سایت خود از مثالهای ساده و زیاد موجود در حساب گیت هاب NoCSRF استفاده کنید.
محافظت در برابر حملات CSRF با استفاده از کلاس csrf by Skookum
csrf by Skookum یکی دیگر از کلاسهای php برای محافظت CSRF میباشد. این کلاس رایگان و برای همه در دسترس است. شما میتوانید آن را در برنامهی وب خود کپی و استفاده کنید. برای مشاهدی جزئیات بیشتر به صفحه گیت هاب csrf by Skookum مراجعه فرمایید.
محافظت در برابر حملات CSRF با استفاده از کتابخانه anticsurf
anticsurf یکی از کتابخانههای کوچک php است که میتواند برای جلوگیری از حملات CSRF در وب اپلیکیشنها استفاده شود. این کتابخانه ادعا میکند که محافظی قوی در برابر این نوع حملات است. همچنین از یک توکن یکبار مصرف استفاده میکند که دارای محدودیت زمانی میباشد. با مراجعه به سایت anticsurf میتوانید آن را دانلود کنید و اطلاعات بیشتری به دست آورید.
چگونه یک حمله CSRF ایجاد کنیم؟
ساخت دستی HTML مورد نیاز برای حمله CSRF میتواند وقتگیر باشد. به خصوص در مواردی که درخواست مورد نظر دارای تعداد زیادی پارامتر است و یا موارد دیگری در درخواست وجود دارد. سادهترین راه برای ایجاد یک حمله CSRF، استفاده از CSRF PoC generator (ابزاری برای طراحی راحتتر حمله) است که در مجموعه ابزار Burp Suite Professional قرار دارد.
برای ایجاد یک حمله CSRF مراحل زیر را طی کنید:
- هر نوع درخواستی را که میخواهید تست کنید در Burp Suite Professional انتخاب کنید.
- بر روی منوی سمت راست کلیک و Engagement tools / Generate CSRF PoC را انتخاب کنید.
- با استفاده از Burp Suite میتوانید HTMLهایی را ایجاد کنید که درخواستهای انتخابی را تحریک میکنند (منهای کوکیها، که به طور خودکار توسط مرورگر قربانی اضافه میشوند).
- برای تنظیم دقیق جنبههای مختلف حمله، میتوانید گزینههای مختلف را در CSRF PoC generato تغییر دهید.
- در آخر html تولید شده را در یک صفحه وب کپی کنید. سپس آن را در مرورگری که وب سایت آسیب پذیر در آن باز شده است، مشاهده کنید. پس از آن بررسی کنید که آیا درخواست مورد نظر با موفقیت انجام شده یا خیر.
غیر فعال کردن CSRF بر روی مسیرهای خاص در لاراول
گاهی اوقات بنابر شرایط، نیاز میشود تا در برخی مسیرهای خاص، CSRF را در لاراول غیرفعال کنیم. برای این کار از طریق مسیر زیر به فایل VerifyCsrfToken میرویم.
\App\Http\Middleware\VerifyCsrfToken
در این کلاس آرایه except$ وجود دارد. برای غیرفعال کردن CSRF در مسیرهای خاص، تنها کافی است url مورد نظر را در این آرایه قرار دهیم. پس از انجام این کار، مسیرهای مورد نظر از بررسی CSRF در لاراول خارج میشوند.
چرا باید از قابلیت CSRF Protection در لاراول استفاده کنیم؟
در این مقاله تلاش کردیم تا به طور کامل به توصیف حملات CSRF، چگونگی کارکرد آنها و روشهای جلوگیری از اینگونه آسیبها بپردازیم. توجه داشته باشید که این حفرهی امنیتی یکی از آسیبهای جدی وب سایت است که در صورت رعایت نکردن موارد امنیتی میتواند بسیار خطرناک باشد و یک کسب و کار را یک شبه از بین ببرد. چنانچه از لاراول استفاده میکنید، میتوانید به سادگی با استفاده از قابلیت CSRF Protection در لاراول از اینگونه حملات جلوگیری کنید.