前提
在說xss解決方式時,有一個前提。就是同源政策——浏覽器的同源政策(浏覽器安全的基礎,即使是攻擊腳本也要遵守這法則),限制了來自不同源的“document”或腳本,對目前“document”讀取或設定某些屬性。除了dom、cookie、xmlhttprequest會受到同源政策的限制外,浏覽器加載的一些第三方插件也有各自的同源政策。不過script、img、iframe、link等标簽都可以跨域加載資源,而不受同源政策的限制。
服務端可以幹的事
1. httponly
其實就是現在http協定(https也是可以的)才能讀取cookies,javascript是讀取不到cookies的。支援浏覽器是ie6+、firefox2+、google、safari4+。
javaee給cookie添加httponly的代碼:
ps:對于https,還是可以設定secure字段,對cookie進行安全加密。
這是本質上不是預防xss,而是在被攻破時候不允許js讀取cookie。
2.處理富文本
有些資料因為使用場景問題,并不能直接在服務端進行轉義存儲。不過富文本資料語義是完整的html代碼,在輸出時也不會拼湊到某個标簽的屬性中,是以可以當特殊情況特殊處理。處理的過程是在服務端配置富文本标簽和屬性的白名單,不允許出現其他标簽或屬性(例如script、iframe、form等),即”xss filter“。然後在存儲之前進行過濾(過濾原理沒有去探明)。
java有個開源項目anti-samy是非常好的xss filter:
ps:當然也可以在前端顯示前過濾,但是我覺得,讓前端人員少做東西好,并且服務端隻需要轉一次。
用戶端可以幹的事
1. 輸入檢查
輸入檢查的邏輯,必須放在伺服器端代碼中實作(因為用javascript做輸入檢查,很容易被攻擊者繞過)。目前web開發的普遍做法,是同時在用戶端javascript中和伺服器代碼中實作相同的輸入檢查。用戶端javascript的輸入檢查,可以阻擋大部分誤操作的正常使用者,進而節約服務資源。
ps:簡單說,就是輸入檢查,服務端和用戶端都要做。
另外攻擊者可能輸入xss的地方,例如:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
ps:當然不止這些
2. 輸出檢查
一般就是在變量輸出到html頁面時,使用編碼或轉義的方式來防禦xss攻擊。xss的本質就是“html注入”,使用者的資料被當成了html代碼一部分來執行,進而混淆了原本的語義,産生了新的語義。
觸發xss的地方
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
ps:如果使用jquery,就是那些append、html、before、after等,其實就是拼接變量到html頁面時産生。大部分的mvc架構在模闆(view層)會自動處理xss問題,例如angularjs。
用什麼編碼轉義
主要有htmlencode和javascriptencode這兩個,用戶端和服務端都能做。但是讓後端去做,我感覺是不大靠譜的,因為資料的使用場景可能有幾種,可以在标簽、屬性、或腳本裡(甚至其他終端使用),單單以一種方式去encode是很極限的。
1.htmlencode,就是将字元轉換成htmlentities,一般會轉(&、<、>、"、'、/)這6個字元。
2.javascriptencode,是使用”\“對特殊字元進行轉義。
哪些地方需要編轉義
1.在html标簽、屬性中輸出——用htmlencode
2.在script标簽中輸出——用javascriptencode
3.在事件中輸出——用javascriptencode
4.在css中輸出
用類似javascriptencode的方式。将除了字母、數字外的所有字元都編碼成十六進制形式”\uhh“。
5.在位址中輸出
一般如果變量是整個url,則先檢查變量是否以“http”開頭(不是則幫忙添加http),保證不會出現僞協定類的xss攻擊。然後再對變量進行urlencode。
ps:urlencode會将字元轉換成”%hh“形式。
總結
前端開發人員要注意在正确的地方使用正确的編碼方式,有時為了防禦xss,在一個地方我們需要聯合htmlencode、javascriptencode進行編碼,甚至是疊加,并不是固定一種方式編碼(又是具體情況具體分析)。
一般存儲型xss風險高于反射型xss。反射型xss一般要求攻擊者誘使使用者點選一個包含xss代碼的url連結;而存儲型隻需要使用者檢視一個正常的url連結,當使用者打開頁面時,xss payload就會被執行。這樣漏洞極其隐蔽,且埋伏在使用者的正常業務中,風險很高。(引自白帽子講web安全原文)
本文為原創文章,轉載請保留原出處,友善溯源,如有錯誤地方,謝謝指正。
轉載:http://www.cnblogs.com/lovesong/p/5223989.html