Dom Based Cross Site Scripting یا XSS نوع سوم. نگاهی بر یک چشم انداز با چاشنی XSS از آمیت کلین
DOM Based Cross Site Scripting or XSS of the Third Kind
A look at an overlooked flavor of XSS by Amit Klein
مطلبی رو برای Hiva.ir ترجمه کردم که گفتم خوبه توی وبلاگ خودم هم منتشرش کنم.
بازارگرمی از تمدن:این مطلب یک مطلب عادی نیست و در XSS از نوع DOM به عنوان رفرنس محسوب میشه و خدا میدونه که تا حالا چندصدبار یا حتی چند هزار بار در مقالههای مختلف بهش ارجاع داده شده… و هر هکری که بخواد علمی کار کنه باید این رو بخونه.
DOM Based Cross Site Scripting or XSS of the Third Kind
A look at an overlooked flavor of XSS by Amit Klein
مطلبی رو برای Hiva.ir ترجمه کردم که گفتم خوبه توی وبلاگ خودم هم منتشرش کنم.
بازارگرمی از تمدن:این مطلب یک مطلب عادی نیست و در XSS از نوع DOM به عنوان رفرنس محسوب میشه و خدا میدونه که تا حالا چندصدبار یا حتی چند هزار بار در مقالههای مختلف بهش ارجاع داده شده… و هر هکری که بخواد علمی کار کنه باید این رو بخونه.
آخرین ویرایش ۷/۴/۲۰۰۵
چکیده
همه ی ما می دانیم که XSS چیست؛ درست است؟ این آسیب پذیری زمانی رخ می دهد که داده های مخرب ارسالی (عموما درون صفحه ی HTML همراه با کدهای جاوااسکریپت) به برنامه بازگردانده شده و جزو محتوای HTML چاپ شود که در این صورت، این چاپشدن به معنای اجرای کدهای جاوااسکریپت نیز خواهد بود. خوب، این موضوع غلط است. این موضوع حمله ی XSS هست اما کامل نبوده و نقص آن، مطلبی است که در این مقاله آورده ام. حداقل در برخی از مبانی با همدیگر یکسان نیستند.
حمله ی XSS توصیف شده در بالا از نوع ناپایدار/بازتابی/reflected می باشد. (مثالی از آن داده های مخربی است که به یک صفحه چسانده شده (embedded) و بلافاصله توسط مرورگر و بعد از درخواست بازگردانده می شود.) یا از نوع پایدار/ذخیرهشده/stored است که در آن داده های مخرب در زمان دیگری بازگردانده می شود. اما نوع سومی از حملات XSS نیز وجود دارد که در وهله ی اول مبتنی بر ارسال داده های مخرب به سرور نیست! ممکن است بگویید این تعریف با آنچه که از قبل می دانستیم در تناقض است. از لحاظ فنی این حملات نوع سومی از XSSاند که با نام DOM-Based XSS نیز شناخته می شوند. این مدل جدید از حمله، به خودی خود بحث جدیدی نیست و در واقع تا حدودی اختراع این روش، نتیجهی توجه به جنبه ها و چاشنیهای مختلفی است که البته بسیار جذاب و مهماند.
توسعه دهندگان و برنامه نویسان برنامه ها باید نسبت به DOM Based XSS شناخت پیدا کنند. چرا که این حمله به عنوان تهدیدی برای برنامه های تحت وب شناخته شده و شرایط به وجود آمدن آن با XSS استاندارد متفاوت است. در حال حاضر (سال ۲۰۰۵) تعداد بسیار زیادی از برنامه های تحت وب نسبت به حمله ی DOM-Based XSS آسیب پذیرند و این درحالی است که این صفحات در مقابل سایر حملات استاندارد XSS آسیب پذیر نیستند.
توسعهدهندگان، پشتیانان سایتها و حتی افرادی که سایت ها را از لحاظ امنیتی بازبینی می کنند می بایست با روشهای تشخیص آسیبپذیری DOM-Based XSS و روشهای مقابله با آن آشنا باشند.
مقدمه
فرض بر این است که خوانندگان با XSSهای پایهای آشنایی دارند. XSS عموما به دو دستهی پایدار/persistent/stored و ناپایدار/reflected/non-persistent تقسیمبندی میشود. ناپایدار به این معناست که کدهای جاوااسکریپت مخرب، به محض دریافت یک درخواست http از سمت قربانی، response یا پاسخ http مربوط به آن را توسط سرور چاپ و اجرا می کند.پایدار نیز به معنای آن است که بارگذاری کد در سیستم (سرور) ذخیره شده و ممکن است بعدا در صفحهی آسیبپذیری که به قربانی ارائه میشود، آن کدها نیز الصاق شدهباشند.
همانگونه که در چکیده هم عنوان شد، مبنای این نوع از دسته بندی، بر اساس داده های مخربی است که به سرور ارسال میشوند؛ در نوع اول، این دادهها در زمان دیگری به کاربر برگردانده می شود (پایدار) و در نوع دوم این اتفاق بلافاصله بعد از ارسال به سرور رخ میدهد (ناپایدار) اما این مقاله فراتر از این دسته بندی عمل است.
اگرچه در خصوص دستهبندی ارائهشده مثالهای نقض زیادی وجود ندارد اما شناخت تنها حملهی XSSای که بر بارگذاری یا همان payload الصاق شده به سرور تکیه نمی کند موضوع مهمی بوده و در شناسایی و روش های جلوگیری نقش بسیار بسزایی خواهد داشت.
نمونه و بحث
قبل از توصیف یک سناریوی اولیه و بنیادی، تاکید بر این نکته مهم است که تکنیکهایی که در اینجا از آن ها استفاده می کنیم قبلا نیز به صورت عمومی منتشر شدهاست. بنابراین تکنیکهای استفاده شده مورد جدیدی نخواهد بود. (هرچند ممکن است بعضی از آن ها جدید به نظر آید)
پیش نیازی که برای یک سایت آسیبپذیر لازم است، صفحه ی HTMLای است که از دادههای document.location یا document.URL یا document.referrer به روشی غیر امن، استفاده نماید. (یا هر نوع دیگری که هکر بتواند روی آن تاثیر بگذارد.)
قابل توجه خوانندگانی که با این نوع از اشیاء جاوااسکریپت آشنایی ندارند: زمانی که جاوااسکریپت در مرورگر اجرا میشود، مرورگر کد جاوااسکریپت را با شیهای مختلف که به عنوان DOM یا Document Object Model ارائه می شود، آماده میکند. شیء document سایر شیءها را مدیریت کرده و به واسطهی آن، اکثر خواص و propertyهای صفحه در زمان درخواست مرورگر ساخته میشوند. شی document از زیر-اشیاء (sub-object) دیگری (URL,Location,referrer)ساخته شده و تمام این موارد در سمت مرورگر میباشند (این نکته ی مهمی است که بعدا به آن خواهیم پرداخت)
بنابراین document.URL و document.location نزد مرورگر به عنوان URL صفحات شناخته میشوند. توجه کنید که این اشیاء جزوی از قسمت body در html نبوده و مرورگر آنها را چاپ نمیکند. شی document شامل شی body (که از آن برای نمایش محتوای پارس شده در html استفاده میشود) نمی شود.
استفاده از این نوع از کدهای جاوااسکریپتی که عبارت مربوط به URL را (با استفاده از document.URL یا document.location) پارس میکنند در صفحات HTML رایج بوده و به وسیلهی آن بعضی از کدهای سمت کلاینت اجرا میشوند. در زیر مثالی از آن را مشاهده می نمایید.
فرض کنید که مثال زیر محتوای صفحه ی http://www.vulnerable.site/welcome.html باشد:
<TITLE>Welcome!</TITLE>
Hi
<SCRIPT>
var pos=document.URL.indexOf(“name=”)+5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<BR>
Welcome to our system
…
</HTML>
در شرایط عادی استفاده از این صفحه برای خوش آمدگویی به کاربر بوده و نحوهی استفاده از آن به شکل زیر است:
http://www.vulnerable.site/welcome.html?name=Joe
اما درخواستی مشابه زیر باعث پیادهسازی حملهی XSS می شود:
http://www.vulnerable.site/welcome.html?name=<script>alert(document.cookie)</script>
اما چرا؟ زمانی که مرورگر قربانی این لینک را دریافت می کند، یک درخواست از نوع HTTP به www.vulnerable.site ارسال شده و مرورگر صفحهی HTML بالایی (از نوع استاتیک!) را دریافت میکند. بعد از آن مرورگر قربانی شروع به پارس کردن (parsing) این HTML به DOM می کند. از طرفی DOM دارای شیای به نام document بوده که دارای یک ویژگی (property) به نام URL است و این ویژگی در ارتباط با URLـه صفحهی جاری برای ساخت بخشی از DOM مورد استفاده قرار میگیرد. وقتی این پارسر به کد جاوااسکریپت می رسد، آن را اجرا کرده و HTML خام این صفحه را دستکاری می کند. در نهایت، کد به document.URL ارجاع داده شده و بنابراین قسمتی از این رشته در زمان پارس به HTML الصاق (embedded) خواهد شد. این مورد فورا پارس شده و کد جاوااسکریپت به ((…)alert) می رسد و آن را به عنوان محتوای همان صفحه اجرا خواهد کرد.
بنابراین در این مثال شرایط XSS به وقوع پیوسته است.
نکات
۱. قسمت مربوط به کدهای مخرب (payload) در هیچ زمانی در درون صفحهی خام html الصاق (embedded) نمی شود. (بر خلاف انواع دیگر XSS)
۲. این اکسپلوییت تنها زمانی کار میکند که مرورگر کارکترهای URL را دستکاری نکند. موزیلا به صورت خودکار کارکترهای >و< موجود در document.URL را زمانی که URL به صورت مستقیم در نوار آدرس وارد نشود به ۳C% و ۳E% تبدیل کرده و بنابراین آسیبپذیری موجود در این روش به این شکل قابل اکسپلویت نخواهد بود. این مورد زمانی آسیبپذیر خواهد بود که در حمله، نیازی به >و< (در شکل خام) نباشد.
البته الصاقکردن (embedded) به صورت مستقیم در html تنها یکی از روش های حمله است و سناریوهای مختلفی از حمله وجود دارند که در آنها نیازی به > و < نیست که در این صورت موزیلا نیز به صورت عمومی در برابر این حمله آسیبپذیر خواهد بود.
گریز از روشهای استاندارد جلوگیری و تشخیص
در مثال بالا قسمت payload از طریق کوئری مربوط به درخواست HTTP به سرور ارسال شده و ممکن است راه شناسایی آن مشابه سایر حملات XSS باشد. حمله ی زیر را ملاحظه فرمایید:
http://www.vulnerable.site/welcome.html?notname=<script>(document.cookie)</script>
بنابراین برای جلوگیری از حقهی استفاده از #، نیازمند محدودیتهای بیشتری در سیاستهای امنیتی در پارامتر ارسالی name میباشیم. فرض کنید مقدار زیر را به سرور ارسال کنیم:
http://www.vulnerable.site/welcome.html?notname= <script>alert(document.cookie)<script>&name=Joe
در شرایطی که سیاستهای امنیتی نامهای اضافی در پارامترها را محدود کرده باشد عبارتی مثل foobar می بایست در ابتدا آمده و مقدار آن شامل payload مورد نظر باشد:
http://www.vulnerable.site/welcome.html?foobar=name=<script>alert(document.cookie)<script>&name=Joe
طبق سناریوی موجود در این لینک در صورت نوشتهشدن تمام document.location در صفحه html، کار هکر بسیار راحت خواهد بود (کد جاوااسکریپت با هدف پیدا کردن نام پارامترهای مشخصی پویش نشود). با این کار هکر میتواند به صورت کامل payload مربوط به حمله را با ارسالی به شکل زیر مخفی نماید:
حتی در شرایط بازبینی payload توسط سرور، تنها زمانی سیستم محافظتی جواب می دهد که درخواست ارسالشده به صورت کامل نادیده و یا پاسخ با متنی حاوی پیام خطا جایگزین شود.
منابع ۵ و ۶ را مجددا مشاهده فرمایید. اگر هدر اعتبارسنجی به سادگی توسط یک سیستم محافظتی میانی حذف شود، هیچ تاثیری روی مقدار بازگرداندهشده توسط صفحهی اصلی، وجود نخواهد داشت. همچنین هر گونه تلاش جهت پاکسازی دادهها روی سرور (چه به وسیلهی پاک کردن کارکترهای مخرب و چه به وسیله ی کد کردن آنها) می تواند در برابر این حمله بی اثر باشد.
در خصوص document.referrer نیز مقدار payload از طریق هدر Referrer به سرور ارسال می شود. البته در صورتی که مرورگر یا یک دستگاه میانی، مقدار این هدر را پاک کند، هیچ گونه راهی برای پیدا کردن و دنبال کردن حمله وجود نداشته و به صورت کامل غیر قابل تشخیص میشود. روش های سنتی برای این کار عبارتند از:
- استفاده از کدینگ html برای دادههای خروجی در سمت سرور
- پاک کردن/کدینگ دادههای ورودی مخرب در سمت سرور
که البته در برابر حملات DOM-Based XSS کارساز نخواهد بود!
با توجه به اینکه اسکنرهای آسیب پذیری، از طریق تزریق و اینجکتهای اشتباه (که گاهی از آن با نام فازبندی یا fuzzing یاد میشود) و بر اساس مقادیری که به صفحه بازگردانده می/نمیشود خروجی را ارزیابی کرده و به نتیجه میرسند، اینگونه محصولات در خصوص این نوع از حمله مفید نخواهد بود. (برای این کار ابتدا یک سری کد را در سمت کلاینت و در مرورگر اجرا و تاثیرات آن در زمان اجرا را مشاهده می کنند)
البته اگر برنامه بتواند جاوااسکریپتهای پیدا شده در یک صفحه را به صورت استاتیک آنالیز کند، ممکن است به الگوهای مشکوکی دست یابد. (ادامه را مشاهده کنید.) همچنین اگر برنامه خودش جاوااسکریپتی را اجرا کند (و به درستی روی اشیاء DOM تاثیر بگذارد) و یا از اجراهایی مشابه آن بهره ببرد ممکن است بتوانیم حمله را تشخیص دهیم.
با توجه به اینکه مرورگرها کدهای جاوااسکریپت را در سمت کلاینت اجرا میکنند، اسکنرهای دستی که از مرورگر استفاده مینمایند می توانند در تشخیص این نوع از آسیبپذیری کار آمد باشد. هرچند ممکن است محصولاتی وجود داشتهباشند که محیطی مشابه مرورگر را شبیهسازی کرده و کدهای جاوااسکریپت را در آن محیطها مورد وارسی قرار دهند.
راه های دفاعی موثر
- از بازنویسی مستندات، ریدایرکتشدن یا سایر اقدامات حساس که با استفاده از دادههای حساس در سمت کاربر صورت میپذیرد، جلوگیری کنید. بسیاری از این کارها را میتوان با استفاده از صفحات پویا و در سمت سرور انجام داد.
- کدهای (جاوااسکریپت) سمت کاربر را به دقت آنالیز کنید. ارجاعاتی که به اشیاء DOM میشود و امکان تاثیرگذاری روی آن توسط کاربر (هکر) وجود دارد میبایست به صورت جدی مورد بازرسی قرار گیرد و این بازرسی شامل موارد زیر می شود. (البته به این موارد محدود نمی شود.):
- document.URL
- document.URLUnencoded
- document.location (and many of its properties)
- document.referrer
- window.location (and many of its properties)
توجه داشته باشید که شی document، شی windows و سایر مشتقات آنها ممکن است به صورتهای مختلف مورد ارجاع قرار گیرند. مثل windows.location،ا location و یا با استفاده از یک هندلکننده به یک windows و استفاده از آن (برای مثال handle_to_some_window.location )
توجه ویژهای به سناریوهای مختلفی که به وسیلهی آن DOM مورد دستکاری و تغییر قرار می گیرد داشته باشید. این سناریوها شامل روشهای مستقیم، دسترسی از طریق HTML خام، دسترسی مستقیم به DOM و … میشوند. برای مثال
- Write raw HTML, e.g.:
- document.write(…)
- document.writeln(…)
- document.body.innerHtml=…
- Directly modifying the DOM (including DHTML events), e.g.:
- document.forms[0].action=… (and various other collections)
- document.attachEvent(…)
- document.create…(…)
- document.execCommand(…)
- document.body. … (accessing the DOM through the body object)
- window.attachEvent(…)
- Replacing the document URL, e.g.:
- document.location=… (and assigning to location’s href, host and hostname)
- document.location.hostname=…
- document.location.replace(…)
- document.location.assign(…)
- document.URL=…
- window.navigate(…)
- Opening/modifying a window, e.g.:
- document.open(…)
- window.open(…)
- window.location.href=… (and assigning to location’s href, host and hostname)
- Directly executing script, e.g.:
- eval(…)
- window.execScript(…)
- window.setInterval(…)
- window.setTimeout(…)
در تکمیل مثال بالا، یک راه دفاعی کارساز و موثر این است که قسمتی از اسکریپت اصلی را با کدی که در ادامه آمده است، جایگزین نماییم. در این کد، رشتهای که قرار است در صفحه ی HTML نوشته شود را چک می کند تا تنها از حروف الفبا و اعداد تشکیل شده باشد:
var pos=document.URL.indexOf(“name=”)+5;
var name=document.URL.substring(pos,document.URL.length);
if (name.match(/^[a-zA-Z0-9]$/))
{
document.write(name);
}
else
{
window.alert(“Security error”);
}
</SCRIPT>
برای این توابع می توانید (میبایست) از کتابخانههای عمومی که برای پاکسازی دادهها وجود دارد، استفاده کنید. (برای مثال از مجموعهای از توابع جاوااسکریپت که کار اعتبارسنجی ورودیها و پاکسازی را انجام می دهند)
سطح پایینتری از اقدامات محافظتی این است که در برابر هکر قوانین امنیتی ارائه داده و آن را در کدهای HTML الصاق کنید. فهم این موضوع آسانتر بوده و حمله را نیز آسانتر می کند! در مثال بالا، شرایط بسیار ساده بوده و در سناریوهای پیچیدهتر نیز ممکن است مفید باشد.
۳. به کارگیری سیاستهای بسیار محدودکننده به وسیلهی IPS. برای مثال صفحه ی welcome.html می بایست تنها یک پارامتر به نام name را دریافت کند که به این منظور میبایست محتویات را چک نمود. همچنین در صورت بروز هرگونه مورد غیر مجاز (شامل پارامترهای بیشتر و یا بدون پارامتر) نباید صفحهی اصلی را ارائه کرد. همچنین هر کار غیر مجاز دیگر (شامل هدر Authorization یا هدر Referrer با محتوایی مخرب) می بایست به عدم ارائهی صفحهی اصلی بینجامد. البته حتی با انجام این کارها نیز نمیتوان تضمین کرد که این حمله خنثی خواهد شد.
توضیحی در خصوص آسیبپذیری ریدایرکت
بحث بالا در خصوص XSS است. در حالیکه خیلی از حملات به این شکل صورت میپذیرد که تنها با استفاده از اسکریپتهای سمت کاربر، مرورگر به صورت نا امن به محل دیگری که آسیبپذیر است ریدایرکت خواهد شد.
در این گونه از موارد نیز تکنیک ها و ملاحظات بالا کماکان برقرار است.
نتیجه گیری
از آنجایی که حملات XSS به صورت عمومی اینگونه توصیف می شوند که: «سرور به صورت فیزیکی دادههای کاربر را درون صفحات پاسخ یا response در html الصاق می کند»، باید دانست که نوع دیگری از حملات XSS نیز وجود دارد که تکیهی آن به الصاق دادهها در سمت سرور نیست.
این موضوع زمانی اهمیت دارد که بخواهیم در خصوص راه های تشخیص و جلوگیری از XSS بحث کنیم. در حال حاضر تکنیکهایی که به صورت عمومی مورد بحث است تنها به دادههایی که توسط ورودیهای مخرب کاربر توسط سرور دریافت و در درون صفحات HTML الصاق می شوند، می پردازد. که در این صورت، تکنیکهایی که هم اکنون مورد استفاده قرار می گیرند در تشخیص و جلوگیری از حملاتی که در این مقاله مورد بحث قرار گرفت، ناکارآمد خواهند بود.
تقسیم بندی حملات XSSای که بر پایهی دادههای الصاقی کاربر در سمت سرور تکیه دارند در دو نوع قرار میگیرند: یکی ناپایدار (non-persistent) یا بازتابی (reflected) و نوع بعدی پایدار (persistent) یا ذخیرهشده (stored). به همین دلیل نوع سومی از XSS پیشنهاد میشود که تکیهی آن بر الصاقات سمت سرور نباشد و نام آن را “DOM Based XSS” می گذاریم.
در زیر مقایسه ای بین XSS استاندارد و DOM Based XSS را مشاهده میفرمایید:
XSS استاندارد | DOM Based XSS | |
علت اصلی | الصاق نا امن ورودیهای کاربری در صفحات html به صورت خارج از محدوده | عدم کنترل ارجاعات نا امن و استفاده از آن (در کدهای سمت کلاینت) به شیهای DOM در سروری که صفحات را فراهم کرده است. |
مالک | برنامهنویسان وب (CGI) | برنامهنویسان وب (HTML) |
نوع صفحات | تنها داینامیک و پویا (اسکریپت CGI) | عموما استاتیک (HTML) البته همیشه اینگونه نیست. |
تشخیص آسیب پذیری |
|
|
تشخیص حمله |
|
اگر تکنیکهای گریز قابل اجرا و استفاده باشد، هیچ راهی برای تشخیص وجود ندارد. |
راه های دفاعی موثر |
|
|
منابع
توجه داشته باشید که URLهایی که در زیر آمده در زمان نوشتن این مقاله (۴ جولای ۲۰۰۵) فعال بوده و ممکن است در حال حاضر وجود نداشته باشد. برخی از این موارد به صورت مستندات در زمان نوشتن این مقاله بودهاند و ممکن است بعد از نوشتهشدن این مقاله، به روز و اصلاح شوند.
درباره نویسنده
Amit Klein به عنوان یک محقق امنیتی برنامههای تحت وب شناخته میشود. آقای کلین دارای مقالات تحقیقی مختلفی در خصوص تکنولوژیهای مختلف در برنامههای تحت وب است. –از HTTP گرفته تا XML، SOAP و وب سرویسها — و عناوین مختلفی را مورد بررسی قرار داده است از جمله قاچاق درخواستهای HTTP، ایندکسگذاری به صورت نا امن، تزریق XPath به صورت کور (blind)، تکهتکهسازی پاسخهای HTTP،ایمنسازی برنامههای تحت وب NET. مسمومسازی کوکیها، XSS و غیره. کارهای وی در مجله ی Dr. Dobb، نشریهی SC، مجلهی ISSA و مجله ی IT Audit منتشر و در کنفرانس های CERT و SANS ارائه و در منابع و سرفصلهای مختلف آکادمیک از آن استفاده شدهاست.
آقای کلین عضوی از WASC است. (Web Application Security Consortium یا کنسرسیوم امنیت برنامه های تحت وب)
لینک مقاله:
http://www.webappsec.org/projects/articles/071105.shtml
دیدگاه خود را ثبت کنید
تمایل دارید در گفتگو شرکت کنید؟نظری بدهید!