آسیبپذیریهای XSS یکی از رایجترین آسیبپذیریهای وب هستند که بخش بزرگی از حملات را به خود اختصاص دادهاند. این حمله به سه شکل اصلی انجام میشود، که Reflected XSS یکی از آنهاست. در این مقاله درباره عواقب و دامنه تاثیرات حملات Reflected XSS صحبت میکنیم و نحوهی یافتن این نوع آسیبپذیری را به طور کامل توضیح خواهیم داد.
اسکریپتنویسی بینسایتی Reflected چیست؟
آسیبپذیری Reflected XSS زمانی به وجود میآید که یک اپلیکیشن داده را در یک ریکوئست HTTP دریافت میکند، و همان داده را بدون رعایت ملاحظات امنیتی و به طور مستقیم در پاسخ آن ریکوئست استفاده میکند – یا بازتاب (reflect) میدهد؛ به همین خاطر است که به این نوع حمله Reflected XSS میگویند.
وبسایتی را فرض کنید که قابلیت جستجو دارد و عبارت جستجوشده توسط کاربر را در قالب یک پارامتر URL دریافت میکند:
https://insecure-website.com/search?term=gift
اپلیکیشن عبارت جستجوشده را عیناً در پاسخ به این URL استفاده میکند:
<p>You searched for: gift</p>
فرض کنید اپلیکیشن هیچ پردازش دیگری روی این داده انجام نمیدهد؛ در این صورت مهاجم میتواند به جای پارامتر مخصوص کلمهی مورد جستجو در URL، یک اسکریپت مخرب قرار دهد:
https://insecure-website.com/search?term=<script>/*+Bad+stuff+here…+*/</script>
این URL باعث میشود اپلیکیشن این پاسخ را بدهد:
<p>You searched for: <script>/* Bad stuff here… */</script></p>
اگر یکی از کاربران اپلیکیشن این URL طراحیشده توسط مهاجم را ریکوئست کند، اسکریپت مهاجم در مرورگر قربانی اجرا میشود؛ نکتهی مهمی که در اینجا وجود دارد، این است که وقتی این اسکریپت در مرورگر کاربر قربانی اجرا میشود، در چارچوب سشن آن کاربر با اپلیکیشن اجرا میشود و به همین خاطر برای آن کاربر بهشدت خطرناک است، چون عملا هر دسترسی که کاربر در اپلیکیشن داشته باشد، آن اسکریپت هم همان دسترسیها را دارد.
عواقب و دامنه تاثیرات حملات Reflected XSS
در صورتی که یک مهاجم بتواند اسکریپتی را که در مرورگر قربانی اجرا میشود کنترل کند، معمولا میتواند به طور کامل دسترسیهای آن کاربر را به دست آورد. در چنین مواقعی دست هکر برای انجام اقدامات مختلف بهشدت باز است؛ برای مثال چند مورد از اقداماتی که مهاجم میتواند انجام دهد عبارتند از:
- انجام هر اقدامی در اپلیکیشن که کاربر میتواند انجام دهد.
- دیدن هر اطلاعاتی که کاربر میتواند ببیند.
- دستکاری هر اطلاعاتی که کاربر میتواند تغییر دهد.
- تعاملکردن با دیگر کاربران آن اپلیکیشن؛ این تعاملات میتوانند حملات مخربی باشند که در ظاهر به نظر میرسد توسط کاربر قربانی اصلی (که حساب او در کنترل مهاجم است) انجام شدهاند.
مهاجم به روشهای متنوعی میتواند کاری کند که کاربر قربانی، ناآگاهانه ریکوئستهایی بزند که در کنترل مهاجم هستند، و از این طریق حمله Reflected XSS را انجام دهد. برای مثال هکر میتواند لینک را روی وبسایتی قرار دهد که در کنترل خودش است، یا آن را روی وبسایت دیگری قرار دهد که اجازهی تولید محتوا را میدهد (مثل medium یا ویرگول) یا لینک را از طریق ایمیل، توییت یا نوع دیگری از پیام برای قربانی بفرستد. با این حمله میتوان مستقیماً یک کاربر خاص را هدف قرار داد، یا میتوان آن را بهگونهای انجام داد که برای تمام کاربرها و اپلیکیشنها یکسان عمل کند.
از آنجایی که این نوع حمله به یک مکانیزم خارجی برای تکمیل فاز انتقال نیاز دارد، معمولا دامنه تاثیرات و عواقب آن شدت کمتری نسبت به Stored XSS دارند؛ حمله Stored XSS، حملهای کاملا مستقل است که میتوان فقط با استفاده از اپلیکیشن آسیبپذیر آن را انجام داد.
نحوه یافتن و تست آسیبپذیریهای Reflected XSS
اکثر آسیبپذیریهای Reflected XSS را به راحتی و به سرعت و البته با ضریب اطمینان بالا، میتوان با استفاده از اسکنر آسیبپذیری وب Burp Suite پیدا کرد. اما برای یافتن، آسیبپذیریهای Reflected XSS به صورت دستی، مراحل زیر باید طی شوند:
- تست تمام نقاط ورودی (entry points): تمام راههای واردکردن داده به اپلیکیشن از طریق ریکوئستهای HTTP را تست کنید؛ از جمله پارامترها و دادههای دیگر داخل استرینگ کوئری URL و بدنهی پیام HTTP، و مسیر فایل URL. و البته هدرهای HTTP را هم فراموش نکنید، گرچه آندسته از رفتارهای XSS در اپلیکیشن که فقط توسط هدرهای خاص HTTP ایجاد میشوند، ممکن است عملا قابل اکسپلویت نباشند.
- ثبت حروف و اعداد تصادفی: در هر جایی که میشود دادهای وارد کرد، یک مقدار تصادفی ولی خاص و قابل تشخیص وارد کنید و بعد بررسی کنید که آن مقدار در پاسخ اپلیکیشن بازتاب شده (reflect شده) یا نه – یعنی اپلیکیشن آن را به طور مستقیم در پاسخ خود استفاده کرده یا نه. این مقدار را طوری طراحی کنید که از فیلترهای اعتبارسنجی ورودی عبور کند، یعنی نسبتا کوتاه باشد و فقط حاوی کاراکترهای حروف و اعداد باشد. ولی دقت کنید که به اندازه کافی هم طولانی باشد تا به صورت اتفاقی با محتوای پاسخ مطابقت پیدا نکند. معمولا یک مقدار تصادفی متشکل از 8 کاراکتر حروف و اعداد برای این کار ایدهآل است.
- تعیین بستر (context) بازتاب مقدار تصادفی: در هرجایی از پاسخ اپلیکیشن که مقدار تصادفی بازتاب شده بود، بستر بازتاب مقدار را مشخص کنید؛ مثلا ممکن است در متنی میان تگهای HTML، یا داخل یکی از attributeهای یک تگ و بین علامتهای دابلکوتیشن (“) یا حتی داخل یک استرینگ جاوااسکریپت بازتاب شده باشد.
- یک پیلود انتخاب کرده و تست کنید: بر اساس این که محتوا در چه بستری بازتاب شده، یک پیلود اولیهی XSS انتخاب کنید و تست کنید که باعث اجرای کد جاوااسکریپت میشود یا نه، و همچنین بدون تغییر در پاسخ اپلیکیشن ظاهر میشود یا نه.
- پیلودهای دیگر را امتحان کنید: اگر پیلود XSS انتخابشده توسط اپلیکیشن دستکاری یا به طور کامل بلاک شده بود، باید پیلودها و تکنیکهای جایگزین را تست کنید. این پیلودها و تکنیکها باید براساس بستر بازتاب محتوا در پاسخ اپلیکیشن، و روشهای اعتبارسنجی ورودی در اپلیکیشن انتخاب شوند.
- حمله را در یک مرورگر تست کنید: در نهایت، اگر موفق شدید و توانستید پیلودی را بیابید که کار میکند، حمله را به یک مرورگر واقعی منتقل کنید. برای این کار کافی است URL را در نوار آدرس آن مرورگر وارد کنید، و بررسی کنید که کد جاوااسکریپت تزریقشده کار میکند یا نه. معمولا بهتر است یک کد جاوااسکریپت ساده و قابل تشخیص اجرا کنید تا بتوانید به سرعت موفقیت حمله را متوجه شوید. مثلا میتوانید از اسکریپت alert(document.domain) استفاده کنید که باعث میشود یک پاپآپ روی صفحهی مرورگر نمایش داده شود.
سوالات رایج درباره Reflected XSS
آسیبپذیری Reflected XSS زمانی به وجود میآید که اپلیکیشن ورودی را از ریکوئست HTTP میگیرد و آن ورودی را به صورت مستقیم و بدون انجام ملاحظات امنیتی، در پاسخ همان ریکوئست استفاده میکند. در آسیبپذیری Stored XSS، اپلیکیشن ورودی را ذخیره میکند و آن را بدون رعایت ملاحظات امنیتی، در تمام پاسخهای بعدی خود استفاده میکند.
در حمله Self-XSS هم اپلیکیشن رفتاری شبیه به Reflected XSS دارد، ولی آن را نمیتوان به روشهای معمول، یعنی با استفاده از URL طراحیشده یا ریکوئستهای بین-دامنهای انجام داد؛ در واقع این آسیبپذیری تنها در صورتی قابل اکسپلویت است که خود قربانی پیلود XSS را از طریق مرورگر خودش ثبت کند. انجام موفق حمله self-XSS معمولا مستلزم این است که مهاجم، قربانی را مهندسی اجتماعی کرده و او را متقاعد کند که ورودی خاصی را در مرورگرش وارد کند. به همین خاطر، این حمله معمولا چندان جدی گرفته نمیشود.