Cross Site Scripting - XSS - Part5

سلام دوستان گرامی

در این بخش به بررسی راههای پیشگیری از حملات DOM-Based XSS خواهیم پرداخت. اگر قسمتهای قبلی این مقاله رو نخوندین میتونید از لینکهای زیر استفاده نمایید:

Cross Site Scripting - XSS - Part1

Cross Site Scripting - XSS - Part2

Cross Site Scripting - XSS - Part3

Cross Site Scripting - XSS - Part4

 همچنین در انتها نکاتی در استفاده از زبان جاوا اسکریپت بیان حواهد شد.

روشهای پیشگیری در  DOM-Based XSS

در صورت امکان برنامه میبایست از بکارگیری اسکریپتهای Client-Side بمنظور پردازش اطلاعات DOM و قرار دادن ورودی نامطمئن در صفحه وب اجتناب نماید. در غیر اینصورت از راهکارهای زیر استفاده نمایید:

1.ورودی برنامه را اعتبارسنجی نمایید (Input Validation )

در اینجا Client-Side Validation موثرتر از Server-Side Validation میباشد. اگر مثالی که در قسمت دوم این مقاله در بخش DOM-Based XSS  زده شد را بخاطر بیاورید، با استفاده از اعتبارسنجی ورودی، به نحوی که فقط شامل کاراکترهای Alphanumeric و Whitespace باشد میتوانستیم از حمله مهاجم جلوگیری نماییم.

<script>

    var a = document.URL;

    a = a.substring(a.indexOf("message=") + 8, a.length);

    a = unescape(a);

    var regex = /^([A-Za-z0-9+\s])*$/;

    if (regex.test(a))

        document.write(a);

</script>

به عنوان راهکار مکمل میتوان از Server-Side Validation برای اعتبارسنجی اطلاعات URL استفاده نمود. برای نمونه در مثال فوق اعتبارسنجی سمت سرور میتواند شامل موارد زیر باشد:

1- Query String فقط شامل یک پارامتر باشد.( بعضی از حملات بر مبنای تغییر تعداد پارامترها انجام میگیرد)

2- نام پارامتر حتما مقدار Message باشد.

3- مقدار پارامتر فقط شامل کاراکترهای Alphanumeric میباشد.

2.خروجی را Encode نمایید (Output Encoding)

در اینجا نیز به مانند Reflected & Stored XSS ورودی نامطمئن قبل از قرارگرفتن روی خروجی Document میبایست به روش صحیح Encode شود. در کدهای جاوااسکریپت Context اصلی  JavaScript میباشد و HTML, HTML attribute, URL and CSS  به عنوان Subcontext شناخته میشوند اما مهاجم میتواند با استفاده از متدها و فانکشنهای DOM در جاوااسکریپت  4 تا Context دیگر را مورد حمله قرار دهد. برای مثال در کد زیر آسیب پذیری در HTML Subcontext  اتفاق می افتد.

<script>

var x = '<%= UntrustedVar %>';

var d = document.createElement(‘div’);

d.innerHTML = x;

document.body.appendChild(d);

</script>

در قسمتهای بعد روشهای Encoding متناسب با هر context آمده است:

2.1  قبل از قراردادن ورودی نامطمئن در HTML Subcontext ورودی را ابتدا HTML Encode و سپس JavaScript Encode نمایید:

در داخل جاوااسکریپت متدها و Attribute های مختلفی برای انجام عملیات روی HTML وجود دارد. اگر به این متدها ورودی نامطمئن داده شود باعث آسیب پذیری XSS میشود. برای مثال Attribute هایی مانند innerHTML  و outerHTML  و یا متدهایی مانند .document.write , document.writeln

element.innerHTML = "<HTML> Tags and markup";

element.outerHTML = "<HTML> Tags and markup";

 

document.write("<HTML> Tags and markup");

document.writeln("<HTML> Tags and markup");

روش صحیح اینست که ابتدا ورودی نامطمئن  HTML Encode شود سپس Javascript Encode گردد. برای مثال اگر از ESAPI برای Encoding بخواهیم استفاده نماییم کدهای زیر روش درست را نمایش میدهند:

element.innerHTML="<%=Encoder.encodeForJS(

                           Encoder.encodeForHTML(untrustedData))%>";

document.write("<%=Encoder.encodeForJS(

                     Encoder.encodeForHTML(untrustedData))%>");

2.2  قبل از قراردادن ورودی در HTML Attribute آنرا JavaScript Encode نمایید:

در Attributeهایی غیر از Event Handler ها و یا CSS یا URL Attributes ورودی نامطمئن میبایست JavaScript Encode شود. (در حالت عادی ورودی میباید HTML Attribute Encode شود اما در DOM فقط  لازمست که Javascript Encode شود.). به مثال زیر توجه نمایید:

var x = document.createElement("input");

x.setAttribute("name", "company_name");

x.setAttribute("value", '<%=Encoder.encodeForJS(companyName)%>');

var form1 = document.forms[0];

form1.appendChild(x);

2.3 درزمان قرار دادن ورودی در Event Handler  یا داخل کد جاوا اسکریپت احتیاط نمایید.

توصیه اکید میشود بدلیل ریسک بالا از قرار دادن ورودی نامطمئن در داخل کد جاوا اسکریپت خودداری نمایید زیرا برخلاف  قسمت قبل( روشهای جلوگیری از Stored XSS) که گفته شد در زمان قرار دادن ورودی در Event Handler های تگهای HTML میتوان با JavaScript Encoding جلوی حملات مهاجمین را گرفت، در اینجا در  بسیاری از موارد Javascript Encoding نمیتواند جلوی حملات در داخل کد جاوا اسکریپت را بگیرد. به مثال زیر توجه نمایید:

var x = document.createElement("a");

x.href="#”;

x.setAttribute("onclick", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\

u0032\u0029");

var y = document.createTextNode("Click To Test");

x.appendChild(y);

document.body.appendChild(x);

در مثال فوق با اینکه پارامتر دوم در setAttribute که معادل Javascript Encode شده ورودی (alert(22 است اما همچنان آسیب پذیر نشان میدهد.

اما اگر اینکار اجتناب ناپذیر است از بکار بردن متدهایی که بصورت رشته ای کد جاوا اسکریپت را قبول میکنند خودداری نمایید. از جمله این متدها میتوان به  setAttribute, setTimeout, setInterval, new Function و ... اشاره نمود. میتوان بجای بکاربردن متد setAttribute مستقیما Attributeهای DOM را  مقدار دهی کرد. اما همین کار نیز بطور کامل جلوی حملات DOM-BASED XSS را نمیگیرد. به مثالهای زیر توجه نمایید:

document.getElementById("myLink").onclick = "\u0061\u006c\u0065\u0072\

u0074\u0028\u0032\u0032\u0029";

 

document.getElementById("myLink").onmouseover =\u0074\u0065\u0073\u0074\u0049\u0074;

           function testIt() {

               

               alert("I was called.");

           }

در مثال اول حمله امکانپذیر نیست و با Javascript Encoding جلوی حمله گرفته شده است. اما در مثال دوم حمله امکانپذیر شده است زیرا مقدار Encode شده testIT  که نام یک فانکشن میباشد که برابر است با

\u0074\u0065\u0073\u0074\u0049\u0074

نتوانسته جلوی حمله را بگیرد.

در زبان جاوااسکریپت  میتوان در جاهای مختلفی بجای مقدار واقعی مقدار Javascritpt Encoding را بکار برد.

برای مثال:

for ( var \u0062=0; \u0062 < 10; \u0062++){

    \u0064\u006f\u0063\u0075\u006d\u0065\u006e\u0074                  

    .\u0077\u0072\u0069\u0074\u0065\u006c\u006e

 ("\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064");

}

یا:

var s = "\u0065\u0076\u0061\u006c";

var t = "\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029";

window[s](t);

 

اما برخلاف JavaScript Encoding در تگهایHTML   امکان تزریق ورودیهایی که HTML Encode شده اند وجود ندارد. برای همین برای عبارتی مانند

<a href="…">

عبارتهای زیر که HTML Encode شده اند صحیح نمیباشد:

&#x3c;a href=… &#x3e;

<&#x61; href="…">

بنابراین در زمان استفاده از JavaScript Encoding  احتیاط نمایید.

2.4   قبل از قرار دادن ورودی در URL Attributes آنها را ابتدا URL Encode و سپس Javascript Encode نمایید.

در جاهایی که ورودی نامطمئن در نقش URL قرار میگیرد بایستی ابتدا URL Encode شود و سپس Javascript Encode شود. به مثال زیر توجه کنید:

var x = document.createElement("a");

x.setAttribute("href", '<%=Encoder.encodeForJS(

                           Encoder.encodeForURL(userRelativePath))%>');

var y = document.createTextElement("Click Me To Test");

x.appendChild(y);

document.body.appendChild(x);

در CSS  نیز زمانی که آدرس URL میدهید همین کار بایستی انجام شود. برای مثال:

document.body.style.backgroundImage = "url(<%=Encoder.encodeForJS(

                           Encoder.encodeForURL(companyName))%>)";

 

دوستان عزیز در اینجا راههای جلوگیری از DOM-Based XSS به پایان میرسد اما در ادامه نکات و ملاحظات امنیتی در زمان استفاده از زبان جاوا اسکریپت بیان شده است.

 

ملاحظات امنیتی در استفاده از زبان جاوا اسکریپت:

  • ورودی نامطمئن میبایستی فقط به عنوان Text استفاده شود و از بکارگیری آن  به عنوان کد قابل اجرا در برنامه یا تگهای HTML بپرهیزید.
  • همیشه ورودیهای نامطمئن را در برنامه بصورت رشته های دارای کوتیشن که Javascript Encode شده اند استفاده کنید. برای مثال:

var x = "<%=encodeForJavaScript(UntrustedData)%>";

  • از بکار بردن Property ها و متدهایی که قابلیت پذیرش HTML به عنوان ورودی  را دارند مانند          element.innerHTML و element.outerHTML و document.write و document.writeln  خودداری نمایید اما اگر مجبور به استفاده از این متدها و Propertyها هستید ابتدا ورودی را HTML Encode و سپس Javascript Encode نمایید.
  • برای تبدیل JSON به اشیا جاوا اسکریپت از() eval  استفاده نکنید و در عوض از  Json.parse  و  در jQuery از  jQuery.parseJSON استفاده نمایید. خواندن () text در jQuery   و قراردادن آن به عنوان innerHTML در یک Element دیگر حتی اگر محتوای آن HTMLEncode باشد تهدید جدی میباشد.

به پایان این پست رسیدیم. در قسمت بعدی میخوام در مورد راهکارهای تکمیلی (و یا آنچه که به Defense in Depth گفته میشه) جهت جلوگیری از حملات XSS مطالبی را بگم.

موفق و پیروز باشید

/ 0 نظر / 42 بازدید