在開發網站時最害怕的莫過於開發人員寫出了一個具有被攻擊性的網站,而其實很多開發人員如果一不注意就會踏進了 Cross-Site Scripting(XSS)的地獄,解決方法很簡單但卻也很容易踏進去,以小弟來說就也曾經跳進去很多次,尤其式透過 jQuery 在操作動態網頁時很容易沒想清楚就用錯方法導致 XSS 錯誤發生,所以這邊筆者整理了幾種在撰寫上的技巧來跟大家分享如何防止XSS攻擊。
前言
在開發網站時最害怕的莫過於開發人員寫出了一個具有被攻擊性的網站,而其實很多開發人員如果一不注意就會踏進了 Cross-Site Scripting(XSS)的地獄,解決方法很簡單但卻也很容易踏進去,以小弟來說就也曾經跳進去很多次,尤其式透過 jQuery 在操作動態網頁時很容易沒想清楚就用錯方法導致 XSS 錯誤發生,所以這邊筆者整理了幾種在撰寫上的技巧來跟大家分享如何防止XSS攻擊。
XSS 指令碼攻擊
我們先看下底下這個畫面,這是一個簡單的訊息發送視窗,而倘若今天駭客在視窗內輸入 Javascript 片段,將會造成這樣的結果:
想像一下這是多恐怖的行為,代表駭客只要了解 Javascript 就可以開始擾亂你的網站,值得注意的是如果顯示內容的方式,是讓使用者輸入後送出顯示或是透過 Ajax 取得頁面資料並顯示的話,就需要注意有 XSS 的危險存在。
防範小技巧
1.一般我們在開發網站過程中,有可能為了專案的需求而暫時關閉基本防護的功能,所以在上線前記得檢查一下 web.config 的設定是不是正常。
<system.web>
<pages validateRequest="true" /> //預設為 ture => 開啟防護
</system.web>
2.常見的方法可以利用 Server.HtmlEncode 來對內容進行編碼:
string value = Server.HtmlEncode("<script>alert('XSS 攻擊');</script>");
而如果使用的 .Net Framework 為 4.5的版本可以利用新的方法 AntiXssEncoder.HtmlEncode 來對內容進行編碼:
// 需引用 System.Web.Security.AntiXss;
string value = AntiXssEncoder.HtmlEncode("<script>alert('XSS 攻擊');</script>", true);
3.若使用 ASP.NET MVC 進行開發,在 View 裡利用 Html Helper 顯示資料時也已經幫我過處理大部分的安全性問題。
首先我們先故意做一個會造成 XSS 攻擊的惡意程式碼,這是在 ASP.NET MVC 中的 Controller
public ActionResult Index()
{
TestModel model = new TestModel();
model.XssAtack = "<script>alert('攻擊');</script>";
return View(model);
}
下面示範幾種在 View 中顯示資料的方法,來檢驗各個方法對於 XSS 的防範機制:
@Html.DisplayFor(p => p.XssAtack) 攻擊失敗,顯示純文字
@Html.DisplayForModel() 攻擊失敗,顯示純文字
@Html.EditorFor(P => P.XssAtack) 攻擊失敗,顯示 input 標籤
@Html.Encode(Model.XssAtack) 攻擊失敗,將內容進行編碼
@Html.Raw(Model.XssAtack) // 攻擊成功,跳出 alert 視窗
@Html.DisplayTextFor(P => P.XssAtack) // 攻擊成功,跳出 alert 視窗
測試結果中顯示 Html.Raw 和 Html.DisplayTextFor 會造成 XSS 攻擊的問題,所以在開發 ASP.NET MVC 時也應該小心使用這些 Html Helper,你防止不必要的問題發生,反觀如果需求就是要跳出一段 alert 來提醒使用者,也可以利用這兩種方法來做資料顯示。
4.在 jQuery 中我們也應該小心使用 .html 的方法。
錯誤示範二
<table>
<tbody>
<tr>
<td class="td1"></td>
</tr>
</tbody>
</table>
<script>
var result = "<script>alert('攻擊成功')";
//透過.html的方法會將內容輸出成html,將有機會造成XSS攻擊
$(".td1").html(result);
</script>
如果只是單純顯示 td 內容應該使用 .text 的方法來設定值
$(".td1").text(result);
錯誤示範二
假設我們透過 Ajax 的方式取得表格內容,並利用 .html 設定資料將會發生 XSS 攻擊問題。
Controller:
public JsonResult GetData()
{
var data = new { id = "s001", name = "<script>alert('XSS 攻擊')</script>" };
return Json(data, JsonRequestBehavior.AllowGet);
}
View:
<table id="GridContent">
</table>
<script>
$(function () {
$.getJSON("/Home/GetData/", function (data) {
var tr = "";
tr += "<tr>";
tr += "<td>" + data["id"] + "</td>";
tr += "<td>" + data["name"] + "</td></tr>";
$("#GridContent").html(tr);
});
});
</script>
解決方法可以直接改變原本的寫法,讓我們透過 jQuery 去選取到 $(td) 的物件,並直接對 td 設定值,當然這樣的作法在效能上真的不是很優,畢竟如果自料很多的話會花費很大的效能,當然更精確的作法還是直接從 Server 端就進行編碼來防範這個問題,而當然還是有其他作法像是以 Regex 表示式來對字串進行檢查...,但作法就比較複雜一點了。
5. 透過 Ajax 呼叫時利用 encodeURIComponent 對參數進行編碼
var arg = encodeURIComponent("http://tw.yahoo.com");
$.getJSON("/Home/GetData/", { id: arg },function(data){
// do somthing
});
總結
其實說了那麼多防範的方法,主要的問題還是在於當使用者一開始進行輸入時就該做完整的驗證,不應該讓使用者傳出去的資料有機會出現造成程式的漏洞,前端驗證後端在進行資料把關,才能讓我們的網站把持最佳化。
參考連結
新手發文,如有錯誤煩請告知,感謝。
如果喜歡我的文章請按推薦,有任何問題歡迎下面留言~~~
簽名:
學習這條路很廣,喜歡什麼技術不重要,重要的是你肯花時間去學習