「XSS 你怎麼防範?」這道題目絕對是面試時的常客,也是最基本的資安問題,.Net 早已提供非常方便的防範方式,網路上也有很多前輩們的文章在介紹這些防範方式,我整理起來提供給我自己參考用。
以下是我參考的來源,建議大家直接閱讀這些參考的來源。
- 跨網站指令碼
- [ASP.NET]防止跨網站(XSS)指令碼攻擊
- Microsoft Anti-XSS (Anti-Cross Site Scripting Library) 避免XSS攻擊
- [Security - XSS 類別] 較安全的程式碼撰寫方法 - .NET 控制項篇
- 防止XSS攻擊套件 Microsoft Anti-Cross Site Scripting Library
- 大師兄回來了 - MICROSOFT WEB PROTECTION LIBRARY 4.3.0
XSS (Cross-site scripting)
依據 Wiki 的定義:XSS 是一種網站應用程式的安全漏洞攻擊,是代碼注入的一種。它允許惡意使用者將程式碼注入到網頁上,其他使用者在觀看網頁時就會受到影響。這類攻擊通常包含了HTML以及使用者端腳本語言,就像這樣。
這個是非常危險的事情,有心人士可以透過程式碼阻斷,讓原本應該正常執行的網頁失效,從中插入他預先設計好的程式碼,讓網頁執行他想要做的事情,輕則惡作劇、重則造成個人資料外洩。
如何防範 XSS 攻擊?
ASP.NET MVC 預設已經有防範 XSS 攻擊,如果不刻意取消設定的話,原則上當 ASP.NET MVC 發現帶有疑似 XSS 代碼的參數時,就會出現錯誤畫面。
ASP.NET WebForm 也是一樣有防範
如果有需要傳遞含有 HTML tag 或 script 的參數怎麼辦?
有這個需求的話可以用下面的方式斷開鎖鍊,但是當心你也有可能會因此而斷開魂結。
ASP.NET MVC 可以在 Controller 或 Action 上刻意加上 [ValidateInput(false)]
。
[HttpPost]
[ValidateInput(false)]
public ActionResult Xss(string Text1)
{
ViewBag.Text1 = Text1;
return View("Index");
}
如果要傳遞的參數剛好是 object 的 property,則可以在類別的屬性上加上 [AllowHtml]
。
public class Order
{
public string Text1 { get; set; }
[AllowHtml]
public string Text2 { get; set; }
}
ASP.NET WebForm 則要將 Page Directive 的 ValidateRequest 屬性值改為 false。
自行防範 XSS 攻擊
當我們將這個 ASP.NET 提供給我們的安全防護機制關閉後,代表著我們必須要自己來防範 XSS 的攻擊,以下提供兩種方式。
1. 使用 Server.HtmlEncode()
我們將有 XSS 攻擊疑慮的參數做 Html Encode 之後再拿來使用。
[HttpPost]
[ValidateInput(false)]
public ActionResult Xss(string Text1)
{
ViewBag.Text1 = Server.HtmlEncode(Text1);
return View("Index");
}
2. 使用 AntiXSS 套件過濾 script
從 NuGet 上安裝 AntiXSS 套件,將有 XSS 攻擊疑慮的參數丟入 Sanitizer.GetSafeHtml()
方法或 Sanitizer.GetSafeHtmlFragment()
方法,直接將 script 給過濾掉。
public void Xss()
{
string body = Sanitizer.GetSafeHtml("<div onload=\"alert('xss');\"><script>alert('xss')</script></div>");
//輸出結果
//<html>
//<body>
//<div></div>
//</body>
//</html>
body = Sanitizer.GetSafeHtmlFragment("<div onload=\"alert('xss');\"><script>alert('xss')</script></div>");
//輸出結果
//<div></div>
}
< Source Code >