
بررسی Cross Site Request Forgery
در این بخش از دوره آموزشی OWASP-WSTG به ششمین بخش از استاندارد WSTG با شناسه WSTG-SESS-05 می پردازیم که مربوط به بررسی Cross Site Request Forgery یا CSRF می باشد.
خلاصه
Cross Site Request Forgeryیا CSRF حملهای است که کاربر نهایی را وادار به اجرای اقدامات ناخواسته بر روی یک برنامه کاربردی تحت وب میکند که در حال حاضر در آن احراز هویت شده است. با کمی کمک مهندسی اجتماعی (مانند ارسال یک لینک از طریق ایمیل یا چت)، مهاجم ممکن است کاربران یک برنامه کاربردی وب را مجبور به اجرای اقدامات مورد نظر مهاجم کند.
یک اکسپلویت CSRF موفق میتواند دادهها و عملیات کاربر نهایی را به خطر بیاندازد. اگر کاربر نهایی هدف، دارای حسابی با سطح دسترسی بالاتر مانند admin باشد، حمله CSRF میتواند کل برنامه کاربردی وب را به خطر بیاندازد.
آشنایی با آسیب پذیری CSRF
CSRF به موارد زیر متکی است:
۱. رفتار مرورگر وب با توجه به کنترل اطلاعات مربوط به جلسه مانند کوکیها و اطلاعات احراز هویت HTTP
۲. دانش یک حملهکننده از URL ها، درخواستها یا قابلیتهای کاربردی معتبر موجود در برنامه تحت وب
۳. مدیریت جلسه برنامه تنها متکی بر اطلاعات شناختهشده توسط مرورگر (Known by the browser) است.
۴. وجود تگهای HTML که حضور آنها باعث دسترسی فوری به یک منبع HTTP یا HTTPS میشود؛ برای مثال تگ تصویر که با img مشخص می شود.
بخشهای ۱، ۲ و ۳ برای وجود آسیبپذیری ضروری هستند در حالی که بخش ۴ بهرهبرداری واقعی را تسهیل میکند اما به شدت مورد نیاز نیست.
۱. مرورگرها به طور خودکار اطلاعات مورد استفاده برای شناسایی یک جلسه کاربر را ارسال میکنند. فرض کنید که سایت، میزبان یک برنامه کاربردی وب است و قربانی کاربر فقط به سایت، Authenticate شدهاست. در Response، سایت یک کوکی برای قربانی ارسال میکند که درخواستهای ارسالشده توسط قربانی را با این عنوان که متعلق به یک جلسه Authenticate شده قربانی می باشد، شناسایی میکند. هنگامی که مرورگر مجموعه کوکی را توسط سایت دریافت میکند، به طور خودکار آن را همراه با هر درخواست دیگری که به سایت هدایت میشود، ارسال میکند.
۲. اگر برنامه از اطلاعات مربوط به نشست در URL ها استفاده نکند، آنگاه URL های برنامه، پارامترهای آنها، و مقادیر قانونی ممکن است شناسایی شوند. این کار را می توان با تجزیه و تحلیل کد یا با دسترسی به برنامه و یادداشتبرداری از فرمها و URL های تعبیهشده در HTML یا JavaScript انجام داد.
۳. “Known by the browser” به اطلاعاتی مانند کوکیها یا اطلاعات احراز هویت مبتنی بر HTTP اشاره دارد (مانندBasic Authentication و نه Form-Based Authentication)، که توسط مرورگر ذخیره میشوند و پس از آن در هر درخواست به سمت یک منطقه کاربردی که درخواست احراز هویت میکند، ارائه میشوند. آسیبپذیریهای بحث شده در ادامه برای برنامههای کاربردی که به طور کامل بر این نوع اطلاعات برای شناسایی یک جلسه کاربر متکی هستند، اعمال میشوند.
به خاطر سادگی، GET-accessible URLs را در نظر بگیرید (اگرچه بحث به خوبی برای درخواستهای POST به کار میرود). اگر قربانی قبلا خود را Authenticate کرده باشد، ارسال درخواست دیگر باعث میشود که کوکی به طور خودکار با آن ارسال گردد. شکل زیر دسترسی کاربر به یک برنامه در www.example.com را نشان میدهد.

درخواست GET میتواند توسط کاربر به چند روش مختلف ارسال شود:
• با استفاده از برنامه کاربردی وب
• تایپ URL به طور مستقیم در مرورگر
• دنبال کردن یک لینک خارجی که به URL اشاره میکند.
این مدل از فراخوانیها توسط برنامه غیرقابلتشخیص هستند. به طور خاص، سومی ممکن است بسیار خطرناک باشد. تعدادی از تکنیکها و آسیبپذیریها وجود دارند که میتوانند ویژگیهای واقعی یک لینک را پنهان کنند. این لینک را میتوان در یک پیام ایمیل جای داد، در یک وب سایت مخرب جاسازی نمود که منجر به فریب کاربر شود یا در محتوای میزبانی شده توسط شخص ثالث (مانند یک وب سایت دیگر یا HTML email) ظاهر گردد و به منبعی از برنامه اشاره نماید.
اگر کاربر بر روی لینک کلیک کند، از آنجا که قبلا توسط برنامه کاربردی وب در سایت Authenticate شدهاست، مرورگر درخواست GET را به برنامه کاربردی وب، همراه با اطلاعات احراز هویت (شناسه کوکی نشست) ارسال خواهد کرد. این امر منجر به انجام یک عملیات معتبر بر روی برنامه کاربردی وب میشود که کاربر انتظار آن را ندارد. به عنوان مثال، انتقال وجوه در یک برنامه بانکداری تحت وب.
با استفاده از یک تگ مانند img، همانطور که در بخش شماره ۴ بالا به آن اشاره شد، حتی لازم نیست که کاربر یک لینک خاص را دنبال کند فرض کنید مهاجم یک ایمیل برای کاربر ارسال میکند و او را تشویق میکند تا از یک URL که به صفحهای حاوی HTML (بیش از حد ساده شده) زیر اشاره دارد، بازدید کند.

هنگامی که مرورگر این صفحه را نمایش میدهد، سعی میکند تصویر با بعد صفر مشخص شده (در نتیجه نامرئی) را از https://www.company.example نیز نمایش دهد. این امر منجر به درخواست ارسال خودکار به برنامه کاربردی وب میزبانی شده در سایت میشود. مهم نیست که URL تصویر به یک تصویر مناسب اشاره نکند، زیرا حضور آن عمل درخواست مشخصشده در فیلد src را راهاندازی خواهد کرد. این اتفاق زمانی میافتد که دانلود تصویر در مرورگر غیر فعال نباشد. اکثر مرورگرها دانلود تصاویر را غیرفعال نمیکنند زیرا این موضوع منجر به از کار افتادن برخی از قابلیتهای مورد استفاده برنامههای کاربردی وب خواهد شد.
مشکل در اینجا نتیجه این است:
• تگهای HTML در صفحه منجر به اجرای درخواست HTTP خودکار میشوند (img یکی از آنها است).
• مرورگر هیچ راهی برای گفتن این ندارد که منبع ارجاع شده توسط img یک تصویر قانونی نیست.
• بارگذاری تصویری که بدون توجه به محل منبع تصویر ادعا شده اتفاق میافتد، یعنی فرم و خود تصویر نیازی به قرار گرفتن در یک میزبان یا حتی یک دامنه نیست.
این واقعیت که محتوای HTML غیرمرتبط با برنامه وب ممکن است به اجزای برنامه اشاره داشته باشد و این واقعیت که مرورگر به طور خودکار درخواست معتبری را برای برنامه ارسال میکند، این نوع حمله را امکان پذیر مینماید. هیچ راهی برای جلوگیری از این رفتار وجود ندارد، مگر اینکه تعامل مهاجم با عملکرد برنامه غیرممکن شود.
در محیطهای یکپارچه mail/مرورگر، نمایش یک پیام ایمیل حاوی مرجع تصویر منجر به اجرای درخواست به برنامه وب با کوکی مرورگر مربوطه میشود. پیغامهای پست الکترونیکی ممکن است URL های به ظاهر معتبر تصویر مانند مثال زیر را داشته باشند:

در این مثال، [attacker] یک سایت است که توسط مهاجم کنترل میشود. با استفاده از یک مکانیزم redirect، سایت مخرب ممکن است از http://[attacker]/picture.gifبرای هدایت قربانی http://[thirdparty]/action استفاده کند و action را راهاندازی کند.
کوکیها تنها نمونه درگیر در این نوع آسیبپذیری نیستند. برنامههای کاربردی وب که اطلاعات جلسه آنها به طور کامل توسط مرورگر تامین میشود نیز آسیبپذیر هستند. این شامل برنامههایی است که تنها بر مکانیزمهای احراز هویت HTTP تکیه دارند، زیرا اطلاعات تایید اعتبار توسط مرورگر شناختهشده و به طور خودکار بر روی هر درخواست ارسال میشود. این شامل احراز هویت مبتنی بر فرم نمیشود، که تنها یکبار رخ میدهد و نوعی از اطلاعات مربوط به جلسه را تولید میکند که معمولا یک کوکی است.
فرض کنید که قربانی به یک کنسول مدیریت مبتنی بر وب فایروال وارد شدهاست. برای ورود به سیستم، کاربر باید خود را احراز هویت کند و اطلاعات نشست در یک کوکی ذخیره میشود.
فرض کنید که کنسول مدیریت مبتنی بر وب فایروال یک تابع دارد که به یک کاربر Authenticate شده اجازه میدهد تا یک Rule را که توسط ID عددی آن مشخص شدهاست حذف کند. همچنین این تابع با دریافت مقدار * از کاربر، تمام قوانین را حذف می کند. صفحه حذف در ادامه نشانداده شدهاست. بیایید فرض کنیم که فرم به خاطر سادگی یک درخواست را مطرح میکند.
حذف قانون شماره یک:

حذف همه قوانین:

این مثال به صورت عمدی ساده است، اما به شیوهای ساده شده خطرات CSRF را نشان میدهد.

با استفاده از فرم نشاندادهشده در شکل بالا، وارد کردن مقدار * و کلیک کردن بر روی دکمه حذف، درخواست GET زیر را ارسال خواهد کرد:

این کار تمام قوانین دیواره آتش را حذف خواهد کرد.

کاربر همچنین ممکن است نتایج مشابهی را با ارسال دستی URL زیر تجربه نماید:

این کار می تواند با دنبال کردن یک لینک، به طور مستقیم یا از طریق یک Redirection، به URL بالا صورت پذیرد.
همچنین با دسترسی به یک صفحه HTML با یک تگ img تعبیهشده که به همان URL بالا اشاره میکند، حذف صورت میگیرد.
در تمام این موارد، اگر کاربر در حال حاضر وارد برنامه مدیریت فایروال شده باشد، درخواست موفقیت آمیز خواهد بود و پیکربندی فایروال را اصلاح خواهد کرد. میتوان حملاتی را تصور کرد که برنامههای حساس را هدف قرار میدهند و مزایده خودکار، انتقال پول، سفارشات، تغییر پیکربندی اجزای نرمافزاری مهم و غیره را انجام میدهند.
نکته جالب این است که این آسیبپذیریها ممکن است در پشت فایروال اجرا شوند؛ برای مثال کافی است که لینک مورد حمله و نه به طور مستقیم توسط مهاجم بلکه تنها توسط قربانی قابل دسترسی باشد. به عنوان مثال، در سناریوی مدیریت فایروال که قبلا ذکر شد، بعید است که این سرویس مدیریتی به صورت مستقیم در اینترنت قرار داشته باشد ولی امکان سوء استفاده از آن وجود خواهد داشت.
اهداف تست
معین کنید که آیا انجام درخواستها از جانب کاربر که توسط خود کاربر آغاز نشده است، امکان پذیر است یا خیر.
چگونه تست را انجام دهیم
برنامه کاربردی را بررسی کنید تا مشخص شود که آیا مدیریت جلسه آن آسیبپذیر است یا خیر. اگر مدیریت نشست تنها به مقادیر client-side تکیه کند (اطلاعات موجود برای مرورگر)، برنامه آسیبپذیر است. Client-side values یا مقادیر سمت کلاینت، به کوکیها و HTTP Authentication Credentials اشاره دارد (Basic Authentication و دیگر اشکال HTTP Authentication؛ نه Form-Based Authentication، که یک اعتبار سنجی در سطح برنامه است).
منابع در دسترس از طریق درخواستهای HTTP GET به راحتی آسیبپذیر هستند، اگرچه درخواستهای POST را میتوان از طریق JavaScript خودکار کرد و همچنین آسیبپذیر هستند. بنابراین، استفاده از POST به تنهایی برای اصلاح وقوع آسیبپذیریهای CSRF کافی نیست.
در مورد POST، نمونه زیر میتواند مورد استفاده قرار گیرد.
• یک صفحه HTML مشابه با آنچه در زیر نشانداده شدهاست ایجاد کنید.
• HTML را بر روی یک سایت شخص ثالث یا مخرب قرار دهید.
• لینک صفحه را به قربانی (ها) ارسال کنید و آنها را وادار کنید که بر روی آن کلیک کنند.

در مورد برنامههای کاربردی وب که در آن توسعه دهندگان از JSON برای ارتباط سرور استفاده میکنند، یک مشکل ممکن است با این واقعیت ایجاد شود که هیچ پارامتر پرسوجو با فرمت JSON وجود ندارد، که یک ضرورت با فرمهای self-submitting است. برای دور زدن این مورد، ما میتوانیم از یک فرم خود ارسال یا self-submitting با پیلودهای JSON شامل ورودیهای پنهان برای بهرهبرداری از CSRF استفاده کنیم. ما باید نوع رمزگذاری (enctype) را به text/plain تغییر دهیم تا اطمینان حاصل کنیم که پیلود به صورت as-is تحویل داده میشود. کد اکسپلویت شبیه به موارد زیر خواهد بود:

درخواست POST به شرح زیر خواهد بود:

زمانی که این داده به عنوان یک درخواست POST ارسال میشود، سرور با خوشحالی فیلد نام و رمز عبور را میپذیرد و فیلد با نام padding را نادیده میگیرد چون نیازی به آن ندارد.
Remediation
به OWASP CSRF Prevention Cheat Sheet برای انجام اقدامات پیشگیری مراجعه کنید.