در این مقاله، به بررسی Cross Site Request Forgery – به اختصار CSRF – میپردازیم، چند نمونه از آسیبپذیریهای رایج CSRF را شرح داده و نحوه جلوگیری از حملات CSRF را توضیح میدهیم.
CSRF چیست؟
CSRF یک آسیبپذیری امنیتی وب است که مهاجم را قادر میسازد تا کاربران را وادار به انجام اقدامات کند که قصد انجام آنها را ندارند. CSRF منجر میشود که مهاجم تا حدی قوانین و سیاستهایی را که برای جلوگیری از تداخل وب سایتهای مختلف با یکدیگر طراحی شده است، دور بزند.
به زبان ساده در حمله CSRF، درخواستهای تقلبی به صورت ناخواسته از سوی کاربران معتبر به سایت هدف ارسال کنند.
معمولاً در این نوع حمله، هکرها از کوکیهای مرورگر یا پارامترهای URL برای انجام درخواستهای تقلبی استفاده میکنند. این درخواستها ممکن است عملیات حذف، ویرایش یا افزودن دادهها (CRUD) را در سایت هدف انجام دهند و میتواند منجر به خسارت جدی و نقض امنیت سایت شود.
برای مقابله با حملات CSRF، از تکنیکهایی مانند استفاده از توکن CSRF (CSRF Token) استفاده میشود. توکن CSRF یک رشته تصادفی است که به صورت پنهانی در فرمها یا درخواستهای مربوط به عملیات مهم قرار میگیرد. در هنگام ارسال فرم یا درخواست، این توکن باید همراه با درخواست ارسال شود و سرور بررسی کند که توکن معتبر است یا خیر. با این کار، امکان اجرای درخواستهای تقلبی از طریق حملات CSRF کاهش مییابد.
دامنه تاثیر حمله CSRF چیست؟
چنانچه یک حمله CSRF موفقیتآمیز باشد، مهاجم میتواند کاربر قربانی را وادار نماید تا اقدامی را ناخواسته انجام دهد. به عنوان مثال، این اقدام ناخواسته ممکن است تغییر نشانی ایمیل حسابهای کاربری قربانی، تغییر رمز عبور یا حتی انتقال وجه از حساب قربانی باشد. بسته به ماهیت اقدام صورت گرفته توسط کاربر قربانی، مهاجم ممکن است بتواند کنترل کامل حساب او را به دست آورد. اگر کاربر آسیبپذیر دارای سطح دسترسی ممتازی باشد، مهاجم میتواند با اجرای موفق یک حمله CSRF، کنترل کامل تمامی دادهها، برنامهها و نرمافزارهای کاربردی را در دست بگیرد.
CSRF چگونه کار میکند؟
برای اجرای حمله CSRF سه شرط کلیدی زیر باید وجود داشته باشد:
- اجرای اقدام مرتبط توسط مهاجم: یک اقدام مرتبط در داخل برنامهکاربردی که مهاجم دلیلی برای انجام آن داشته باشد. این اقدام ممکن است شامل تغییر مجوز و سطح دسترسی سایر کاربران یا هر اقدامی در خصوص دادههای خاص کاربر (مانند تغییر رمز عبور خود کاربر) باشد.
- امکان دستدرازی به جلسه جاری (Session) بر مبنای کوکی: انجام این عمل شامل ارسال یک یا چند درخواست HTTP (HTTP Request) است. دراین حالت، برای اینکه حمله CSRF اجرا شود، نرمافزار کاربردی برای شناسایی کاربری که درخواستها را ارسال کرده، تنها به کوکیهای Session متکی است. هیچ مکانیسم دیگری برای ردیابی و پویش Session یا اعتبارسنجی درخواستهای کاربر وجود ندارد.
- قابل پیشبینی بودن تمام پارامترهای درخواست موردنظر: درخواستهایی که منجر به حملات CSRF میشوند نباید حاوی پارامتری باشند که مهاجم نتواند مقادیر آنها را تعیین کند یا حدس بزند. به عنوان مثال، هنگامی که مهاجم کاربر را وادار به تغییر رمز عبور خود میکند، اگر مهاجم نیاز به دانستن مقدار رمز عبور فعلی باشد، کاربر نسبت به تغییر رمزعبور آسیبپذیر نخواهد بود.
به عنوان مثال، فرض کنید یک برنامهکاربردی دارای قابلیتی است که به کاربر اجازه تغییر نشانی ایمیل حساب را میدهد. هنگامی که کاربر این اقدام را انجام میدهد، یک درخواست HTTP مانند زیر ارسال میشود:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
email=wiener@normal-user.com
این درخواست HTTP شرایط لازم برای اجرای یک حمله CSRF را دارا میباشد:
- عمل تغییر نشانی ایمیل مربوط به یکی از حسابهای کاربری. پس از این تغییر نشانی، مهاجم معمولاً قادر به تنظیم مجدد رمز عبور و کنترل کامل حساب کاربری خواهد بود.
- این برنامهکاربردی از کوکی جلسه (Session Cookie) برای تشخیص اینکه کدام کاربر درخواست را ارسال کرده، استفاده میکند. هیچ نشانه یا مکانیزم دیگری برای ردیابی جلساتجاری (Session) کاربر وجود ندارد.
- مهاجم به راحتی میتواند مقادیر پارامترهای درخواستی برای انجام اقدام مورد نیاز را تعیین کند.
با برآورده شدن این سه شرط بالا، مهاجم میتواند صفحه وبی حاوی کد HTML زیر ایجاد نماید:
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
اگر کاربر قربانی از صفحه وب مهاجم بازدید کند، موارد زیر رخ میدهد:
- صفحه مهاجم یک درخواست HTTP را به وب سایت آسیبپذیر ارسال میکند.
- اگر کاربر به وب سایت آسیبپذیر وارد شده باشد (لاگین کرده باشد)، مرورگر او به طور خودکار کوکی جلسه (Session Cookie) خود را در درخواست میآورد (با فرض اینکه از قابلیت SameSite در کوکیها استفاده نشده باشد).
- وبسایت آسیبپذیر درخواست را به روش معمولی پردازش میکند؛ آن را همانند سایر درخواستهای کاربر قربانی، قلمداد نموده و نشانی ایمیل این کاربر را تغییر میدهد.
توجه داشته باشید که…
اگرچه حملات CSRF معمولاً به مدیریت جلسات مبتنی بر کوکی (Cookie-based Session) مربوط میشوند، اما در شرایط دیگری و اصولاً در تمام مواقعی که در آن برنامهکاربردی به طور خودکار برخی از اطلاعات هویتی کاربر را در درخواستها ارسال میکند، این آسیبپذیری بهوجود میآید. به عنوان مثال این آسیبپذیری در احراز هویت پایه HTTP و احراز هویت مبتنی بر گواهینامه (Certificate-based) نیز وجو دارد.
نحوه ایجاد یک حمله CSRF
ساختن دستی صفحه HTML مورد نیاز برای ایجاد یک اکسپلویت CSRF نسبتاً دشوار میباشد، به خصوص در مواردی که درخواست مورد نظر حاوی تعداد زیادی پارامتر باشد یا ریزهکاریهای درخواست زیاد باشد. ساده ترین روش ایجاد یک اکسپلویت CSRF، استفاده ازCSRF PoC Generator است که به صورت پیشفرض در Burp Suite Professional (نسخه Professional نرمافزار Burp Suite) قرار دارد:
- درخواست را در هر جایی از نرمافزار Burp Suite Professional که میخواهید آزمایش کنید یا مورد سوءاستفاده قرار دهید، انتخاب نمائید.
- از منویی که به هنگام کلیک راست کردن باز میشود، گزینه Engagement tools / Generate CSRF PoC را انتخاب کنید.
- Burp Suite به صورت خودکار ضمن تولید یک کد HTML، درخواست انتخاب شده را فعال میکند (البته بدون کوکیها، چون کوکیها به طور خودکار توسط مرورگر قربانی اضافه میشوند).
- میتوانید گزینههای مختلفی را در CSRF PoC Generator تغییر دهید تا جنبههای مختلف حمله را مطابق با میل خودتان تنظیم کنید. ممکن است نیاز باشد در بعضی موقعیتهای غیرمعمول، برای تنظیم بعضی از ویژگیهای خاص و غیرمعمول درخواستها، از این گزینهها استفاده نمائید.
- کد HTTML تولید شده را در یک صفحه وب کپی کنید، آن را در مرورگری که در وب سایت آسیبپذیر لاگین کردهاید مشاهده نمائید و ب کررسینید که آیا درخواست مورد نظر با موفقیت ارسال شده و اقدام موردنظر انجام میشود یا خیر.
نحوه سوءاستفاده از آسیبپذیری CSRF
مکانیسمهای اجرای حملات CSRF اساساً مشابه اجرای حملات Reflected XSS میباشد. به طور معمول، مهاجم، کد HTML مخرب را در وبسایتی که تحت کنترل وی است، قرار میدهد و سپس قربانیان را وادار میکند که از آن وب سایت بازدید کنند. این کد مخرب ممکن است در لینک وب سایت درج شود و یا در ایمیل یا پیام ارسالی در رسانههای اجتماعی برای کاربر قربانی ارسال شود. یا اگر حمله به یک سایت محبوب و پرطرفدار (مثلاً در بخش نظرات کاربران یک سایت پربازدید) انجام شود، مهاجم باید منتظر باشد تا کاربران از وب سایت مذکور بازدید کنند.
توجه داشته باشید که برخی از اکسپلویتهای ساده CSRF از متد GET استفاده میکنند؛ در این صورت میتوانند به طور کامل در یک URL از وبسایت آسیبپذیر قرار بگیرند. در این شرایط، مهاجم دیگر نیازی به استفاده از یک سایت خارجی ندارد و میتواند مستقیماً یک URL مخرب مربوط به دامنه آسیبپذیر را به قربانیان ارسال کند. در مثال قبل، اگر درخواست تغییر نشانی ایمیل با متد GET انجام شود، آنگاه حمله حاوی کدمخرب به شکل زیر خواهد بود:
<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">
مقابله با حملات CSRF
امروزه، شناسایی آسیبپذیریهای CSRF و سوءاستفاده موفقیتآمیز از آنها شامل دور زدن قوانین ضد CSRF یا Anti-CSRF measures است که از طریق وبسایت موردنظر، مرورگر قربانی یا هر دو صورت میگیرد. متداولترین اقدامات جهت پیشگیری از حملات CSRF عبارتند از:
- CSRF token: یک توکن CSRF، مقداری منحصر به فرد، مخفی و غیرقابل پیشبینی است که توسط برنامهکاربردی سمت سرور (Server-side Application) تولید شده و با Client به اشتراک گذاشته میشود. هنگام تلاش برای انجام عملی محرمانه مانند ارسال یک فرم، Client باید توکن صحیح CSRF را در درخواست وارد کند. این امر ایجاد و ارسال یک درخواست معتبر به قربانی را برای مهاجم بسیار دشوار مینماید.
- SameSite cookies: یک مکانیسم امنیتی مرورگر است که تعیین میکند کوکیهای یک وبسایت چه زمانی در درخواستهای ارسال از سایر وبسایتها، گنجانده شوند. از آنجایی که درخواستهای انجام اقدامات محرمانه معمولاً به یک Session cookie تأیید شده نیاز دارند، محدودیتهای SameSite ممکن است مانع از اجرای حملات CSRF توسط مهاجم شود. از سال 2021، مرورگر کروم (Chrome) به طور پیشفرض محدودیتها و قوانین Lax SameSite را اعمال میکند. انتظار داریم سایر مرورگرهای متداول نیز در آینده این استاندارد پیشنهادی را اتخاذ کنند.
- Referer-based validation: برخی از برنامهها با بکارگیری هدر HTTP Referer و با اعتبارسنجی اینکه درخواست از دامنه خود برنامه نشات گرفته، در برابر حملات CSRF دفاع میکنند. این تکنیک به طور کلی نسبت به اعتبارسنجی توکن CSRF کمتر موثر است.
توکن CSRF چیست؟
توکن CSRF یک مقدار منحصر به فرد، مخفی و غیرقابل پیش بینی است که توسط برنامه سمت سرور تولید شده و با کلاینت به اشتراک گذاشته می شود. هنگام صدور درخواست برای انجام یک عمل حساس، مانند ارسال فرم، کلاینت باید توکن CSRF صحیح را وارد کند. در غیر این صورت سرور از انجام عمل درخواستی خودداری خواهد کرد.
یک راه متداول برای به اشتراک گذاری توکن های CSRF با کلاینت این است که آنها را به عنوان یک پارامتر مخفی در یک فرم HTML قرار دهید، به عنوان مثال:
<form name="change-email-form" action="/my-account/change-email" method="POST">
<label>Email</label>
<input required type="email" name="email" value="example@normal-website.com">
<input required type="hidden" name="csrf" value="50FaWgdOhi9M9wyna8taR1k3ODOR8d6u">
<button class='button' type='submit'> Update email </button>
</form>
این توکن که در یک فیلد مخفی است از دید کاربر عادی پنهان است، ولی در کدهای صفحه مورد نظر قابل مشاهده میباشد، که البته در صورت دستکاری این کد و به دلیل تفاوت با همتای آن در سرور، عملیات مورد نظر تایید نخواهد شد.
ارسال این فرم منجر به ارسال درخواست زیر می شود:
POST /my-account/change-email HTTP/1.1
Host: normal-website.com
Content-Length: 70
Content-Type: application/x-www-form-urlencoded
csrf=50FaWgdOhi9M9wyna8taR1k3ODOR8d6u&email=example@normal-website.com
هنگامی که توکنهای CSRF به درستی پیادهسازی شوند، با ایجاد مشکل برای مهاجم در ایجاد یک درخواست معتبر از طرف قربانی، به محافظت در برابر حملات CSRF کمک میکنند. از آنجایی که مهاجم هیچ راهی برای پیشبینی مقدار صحیح توکن CSRF ندارد، نمیتواند آن را در درخواست مخرب وارد کند.