۱۳۸۷/۰۸/۲۰

بررسي Microsoft Anti-Cross Site Scripting Library


هنگام نمايش اطلاعات در وب بايد اطلاعات خام دريافتي از كاربر را encode كرده و سپس نمايش داد تا از حملات XSS يا cross site scripting attacks در امان ماند. مثلا وبلاگي را طراحي كرده‌ايد و يك نفر اطلاعات زير را بجاي توضيحات ارسال كرده است:
<SCRIPT>alert('XSS')</SCRIPT>

اگر اطلاعات به همين شكل دريافت و بدون تغيير هم نمايش داده شود، يك ضعف امنيتي براي سايت شما به‌حساب خواهد آمد. (بحث دزديدن اطلاعات كوكي و امثال آن از اين طريق با معرفي HttpOnly cookies در IE‌هاي جديد و فايرفاكس 3 به بعد تقريبا منتفي شده است اما مي‌توانند با ارسال انبوهي اسكريپت، مشاهده صفحه را با crash‌ كردن مرورگر كاربران همراه كنند)
مايكروسافت براي اين منظور Microsoft Anti-Cross Site Scripting Library را ارائه داده است. نمونه بهبود يافته HttpUtility.HtmlEncode كه در فضاي نام System.Web موجود است.

در اينجا قصد داريم اين كتابخانه را با ليست زير آزمايش كنيم:
http://ha.ckers.org/xss.html
در همان صفحه اگر دقت كنيد، ليست حملات را به صورت يك فايل xml هم ارائه داده است:
http://ha.ckers.org/xssAttacks.xml
براي خواندن اين فايل xml در دات نت روش‌هاي زيادي وجود دارد منجمله XML serialization .

ساختار اين فايل به شكل زير است:
<?xml version="1.0" encoding="UTF-8"?>
<xss>
<attack>
<name>x1</name>
<code>x2</code>
<desc>x3</desc>
<label>x4</label>
<browser>x5</browser>
</attack>
.
.
.

بنابراين شيء‌ نمايانگر آن مي‌تواند به صورت ليستي از كلاس زير باشد:
    public class attack{
public string name { get; set; }
public string code { get; set; }
public string desc { get; set; }
public string label { get; set; }
public string browser { get; set; }
}

براي دريافت اين ليست و بارگذاري فايل xml مربوطه با استفاده از روش XML serialization خواهيم داشت:
      
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

public static List<attack> DeserializeFromXML(string path)
{
XmlRootAttribute root = new XmlRootAttribute("xss");
XmlSerializer deserializer =
new XmlSerializer(typeof (List<attack>),root);
using (TextReader textReader = new StreamReader(path))
{
return (List<attack>)deserializer.Deserialize(textReader);
}
}

در ادامه فرض بر اين است كه ارجاعي از اسمبلي AntiXssLibrary.dll به پروژه اضافه شده است، همچنين فايل xssAttacks.xml فوق نيز در كنار فايل اجرايي برنامه ، مثلا يك برنامه كنسول قرار گرفته است:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.Security.Application;

private static void testMethod()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<html>{0}", Environment.NewLine);
sb.AppendFormat("<body>{0}", Environment.NewLine);

List<attack> data = XMLParser.DeserializeFromXML("xssAttacks.xml");
foreach (attack atk in data)
{
string cleanSafeHtmlInput = AntiXss.HtmlEncode(atk.code);
sb.AppendFormat("{0}<br>{1}", cleanSafeHtmlInput, Environment.NewLine);
}

sb.AppendFormat("</body>{0}", Environment.NewLine);
sb.AppendFormat("</html>");

File.WriteAllText("out.htm", sb.ToString());
}

پس از اجراي تابع فوق، خروجي ما يك فايل html خواهد بود به نام out.htm . آنرا در مرورگر خود باز كنيد. بدون هيچ مشكلي باز خواهد شد و خروجي امني را مشاهده خواهيد كرد. براي مشاهده اثر واقعي اين كتابخانه، قسمت AntiXss.HtmlEncode را از كد فوق حذف كنيد و يكبار ديگر برنامه را اجرا كنيد. اكنون فايل نهايي را در مرورگر باز كنيد. با انبوهي از alert هاي جاوا اسكريپتي مواجه خواهيد شد كه اهميت كتابخانه فوق را جهت ارائه خروجي امن در صفحات وب مشخص مي‌سازد.