فریمورک محبوب لاراول، در عین سادگی دارای نکات و جزئیات فراوانی است که یادگیری آنها نیازمند دقت و صرف زمان مناسب میباشد. یکی از نکات مهم در بحث امنیت، حفاظت CSRF در لاراول میباشد که از وب اپلیکیشنها در برابر حملات Cross-Site Request Forgery محافظت میکند. شناخت این نوع از حملات و راههای مقابله با آنها یکی از موارد مهمی است که هر برنامه نویس لاراول باید از آن آگاهی داشته باشد.
اگر برنامه نویس لاراول هستید و یا دارای وب سایت میباشید و نمیخواهید وب سایت شما با حمله CSRF در لاراول آسیب ببیند، تا انتهای این مقاله با وب سایت آموزش برنامه نویسی سون لرن همراه باشید.
CSRF مخفف Cross-Site Request Forgery میباشد که به معنای جعل درخواست از طریق سایت است. CSRF یک حفره امنیتی در وب است که به مهاجم اجازه میدهد تا کاربران را وادار به انجام کارهایی کند که قصد انجام آنها را ندارند. این حمله به مهاجم این اختیار را میدهد تا سیاستهایی که برای جلوگیری از دخالت وب سایتهای مختلف در کار یکدیگر طراحی شدهاند را دور بزند. به عنوان مثال فرض کنید، کاربران سایت google.com با وارد کردن آدرس google.com/logout کوکی مرورگرشان حذف میشود و در نتیجه logout میشوند. حال اگر یکی از کاربران در یک سایت دیگر (مثلاً در یک انجمن شلوغ) تصویری با تگ img زیر ارسال کند و افراد دیگر حاضر در آن انجمن این تصویر را مشاهده کنند، از طرف مرورگرشان درخواستی به سایت گوگل ارسال میشود و موجب میشود تا همه کسانی که آن تصویر را دیدهاند از اکانت گوگلشان بیرون انداخته شوند.
<img src="https://www.google.com/logout/" alt="" />
البته این مثال یک نمونه ساده و غیر خطرناک بود. حالتهای بسیار خطرناک دیگری نیز وجود دارد.
CSRF باعث میشود برنامههای وب نتوانند بین درخواستهای معتبر و درخواستهای جعلی کنترل شده توسط مهاجم تمایز قائل شوند. روشهای زیادی وجود دارد که یک مهاجم سعی میکند از حفره امنیتی CSRF استفاده کند. در ادامه برای درک بهتر این نوع حملات، با ذکر یک مثال به توصیف چگونگی حملات CSRF در لاراول میپردازیم.
فرض کنید، شخصی به نام باب یک حساب بانکی آنلاین در سایت samplebank.com دارد. او مرتباً برای انجام معاملات خود از این سایت بازدید میکند. باب اطلاعی ندارد که samplebank.com در برابر حملات CSRF آسیب پذیر است. در همین حال یک مهاجم قصد دارد با استفاده از این حفرهی امنیتی 5000 دلار از حساب باب به حساب دیگر منتقل کند.
برای انجام موفقیت آمیز این حمله:
در ادامه، باب برای انتقال پول در سایت بانک، یک درخواست با روش 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 برخی محدودیتها وجود دارد. از جمله:
لاراول یک راهکار آسان به نام CSRF Protection برای محافظت در برابر حملات CSRF ارائه داده است. حفاظت CSRF در لاراول به این صورت است که به ازای هر کاربر فعال در اپلیکیشن، برنامه یک توکن CSRF تولید میکند. این توکن برای تایید این است که آیا درخواستی که ارسال میشود از سمت یک شخص واقعی است یا خیر.
هر وقت شما یک فرم HTML که با تگ <form> شناخته میشود را در صفحه ایجاد میکنید، حتماً باید توکن CSRF را در داخل آن قرار دهید، تا حفاظت CSRF در لاراول بتواند درخواست را تایید کند. در صورتی که این کار را انجام ندهید درخواست شما faild یا ریجکت میشود. برای انجام این کار تنها کافی است عبارت CSRF@ را در داخل تگ فرم خود قرار دهید. مانند کد زیر:
<form method="POST" action="/profile">
@csrf
...
</form>
میدلور VerifyCsrfToken که در گروه میدلورهای وب قرار دارد، به طور خودکار تایید میکند که توکن موجود در درخواست با توکن ذخیره شده در session مطابقت دارد یا خیر.
در ادامه به معرفی چند روش برای جلوگیری از اینگونه آسیبها در php میپردازیم.
این کار میتواند به جلوگیری از حملات CSRF کمک کند. اگر درخواست از دامنه دیگری ارسال شده باشد، این درخواست حتماً جعلی است بنابراین باید مسدود شود.
تایید 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 یک مقدار منحصر به فرد، مخفی و غیر قابل پیش بینی است که توسط برنامه در سمت سرور تولید و در هر درخواست کاربر گنجانده میشود. هنگامی که درخواست کاربر ارائه میشود، برنامه در سمت سرور تایید میکند که این درخواست شامل توکن مورد انتظار است، در صورت عدم وجود و یا نامعتبر بودن آن، درخواست توسط برنامه رد میشود. میزان تأثیر توکن به روش تولید آن بستگی دارد، بنابراین همیشه سعی کنید توکن را به روشی تولید کنید که غیر قابل پیش بینی باشد.
برای تولید توکن میتوانید از کد زیر استفاده کنید.
$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 میپردازیم. این موارد عبارتند از:
NoCSRF یک کلاسهای ساده و ضد حمله CSRF است که کار تولید توکن را انجام میدهد. همچنین شما میتوانید برای یادگیری نحوی پیاده سازی این کلاس در وب سایت خود از مثالهای ساده و زیاد موجود در حساب گیت هاب NoCSRF استفاده کنید.
csrf by Skookum یکی دیگر از کلاسهای php برای محافظت CSRF میباشد. این کلاس رایگان و برای همه در دسترس است. شما میتوانید آن را در برنامهی وب خود کپی و استفاده کنید.
anticsurf یکی از کتابخانههای کوچک php است که میتواند برای جلوگیری از حملات CSRF در وب اپلیکیشنها استفاده شود. این کتابخانه ادعا میکند که محافظی قوی در برابر این نوع حملات است. همچنین از یک توکن یکبار مصرف استفاده میکند که دارای محدودیت زمانی میباشد. با مراجعه به سایت anticsurf میتوانید آن را دانلود کنید و اطلاعات بیشتری به دست آورید.
ساخت دستی HTML مورد نیاز برای حمله CSRF میتواند وقتگیر باشد. به خصوص در مواردی که درخواست مورد نظر دارای تعداد زیادی پارامتر است و یا موارد دیگری در درخواست وجود دارد. سادهترین راه برای ایجاد یک حمله CSRF، استفاده از CSRF PoC generator (ابزاری برای طراحی راحتتر حمله) است که در مجموعه ابزار Burp Suite Professional قرار دارد.
برای ایجاد یک حمله CSRF مراحل زیر را طی کنید:
گاهی اوقات بنابر شرایط، نیاز میشود تا در برخی مسیرهای خاص، CSRF را در لاراول غیرفعال کنیم. برای این کار از طریق مسیر زیر به فایل VerifyCsrfToken میرویم.
\App\Http\Middleware\VerifyCsrfToken
در این کلاس آرایه except$ وجود دارد. برای غیرفعال کردن CSRF در مسیرهای خاص، تنها کافی است url مورد نظر را در این آرایه قرار دهیم. پس از انجام این کار، مسیرهای مورد نظر از بررسی CSRF در لاراول خارج میشوند.
در این مقاله تلاش کردیم تا به طور کامل به توصیف حملات CSRF، چگونگی کارکرد آنها و روشهای جلوگیری از اینگونه آسیبها بپردازیم. توجه داشته باشید که این حفرهی امنیتی یکی از آسیبهای جدی وب سایت است که در صورت رعایت نکردن موارد امنیتی میتواند بسیار خطرناک باشد و یک کسب و کار را یک شبه از بین ببرد. چنانچه از لاراول استفاده میکنید، میتوانید به سادگی با استفاده از قابلیت CSRF Protection در لاراول از اینگونه حملات جلوگیری کنید.
در صورتی که روشهای دیگری برای دفاع در برابر حملات CSRF میشناسید، خوشحال میشویم آنها را در بخش نظرات با دیگر کاربران وب سایت سون لرن به اشتراک بگذارید.