[點(diǎn)晴永久免費(fèi)OA]XSS攻擊的解決方法
在我上一篇《前端安全之XSS攻擊》文中,并沒(méi)有把XSS攻擊的解決辦法說(shuō)完整,而XSS的攻擊又那么五花八門(mén),有沒(méi)有一招“獨(dú)孤九劍”能夠抗衡,畢竟那么多情況場(chǎng)景,開(kāi)發(fā)人員無(wú)法一一照顧過(guò)來(lái),而今天通過(guò)閱讀《白帽子講Web安全》這本書(shū),對(duì)應(yīng)對(duì)方式有了更好的總結(jié),分為兩類(lèi),一是服務(wù)端可以干的事,二是客戶端可以干的事。 前提 在說(shuō)XSS解決方式時(shí),有一個(gè)前提。就是同源策略——瀏覽器的同源策略(瀏覽器安全的基礎(chǔ),即使是攻擊腳本也要遵守這法則),限制了來(lái)自不同源的“document”或腳本,對(duì)當(dāng)前“document”讀取或設(shè)置某些屬性。除了DOM、Cookie、XMLHttpRequest會(huì)受到同源策略的限制外,瀏覽器加載的一些第三方插件也有各自的同源策略。不過(guò)script、img、iframe、link等標(biāo)簽都可以跨域加載資源,而不受同源策略的限制。 服務(wù)端可以干的事 1. HttpOnly 其實(shí)就是現(xiàn)在HTTP協(xié)議(HTTPS也是可以的)才能讀取cookies,JavaScript是讀取不到cookies的。支持瀏覽器是IE6+、Firefox2+、Google、Safari4+。 JavaEE給Cookie添加HttpOnly的代碼: response.setHeader("Set-Cookie","cookiename=value; Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly"); PS:對(duì)于HTTPS,還是可以設(shè)置Secure字段,對(duì)Cookie進(jìn)行安全加密。 這是本質(zhì)上不是預(yù)防XSS,而是在被攻破時(shí)候不允許JS讀取Cookie。 2.處理富文本 有些數(shù)據(jù)因?yàn)槭褂脠?chǎng)景問(wèn)題,并不能直接在服務(wù)端進(jìn)行轉(zhuǎn)義存儲(chǔ)。不過(guò)富文本數(shù)據(jù)語(yǔ)義是完整的HTML代碼,在輸出時(shí)也不會(huì)拼湊到某個(gè)標(biāo)簽的屬性中,所以可以當(dāng)特殊情況特殊處理。處理的過(guò)程是在服務(wù)端配置富文本標(biāo)簽和屬性的白名單,不允許出現(xiàn)其他標(biāo)簽或?qū)傩裕ɡ鐂cript、iframe、form等),即”XSS Filter“。然后在存儲(chǔ)之前進(jìn)行過(guò)濾(過(guò)濾原理沒(méi)有去探明)。 Java有個(gè)開(kāi)源項(xiàng)目Anti-Samy是非常好的XSS Filter: Policy ploicy = Policy.getInstance(POLICY_FILE_LOCATION); AntiSamy as = new AntiSamy(); CleanResults cr = as.scan(dirtyInput, policy); MyUserDao.storeUserProfile(cr.getCleanHTML()); PS:當(dāng)然也可以在前端顯示前過(guò)濾,但是我覺(jué)得,讓前端人員少做東西好,并且服務(wù)端只需要轉(zhuǎn)一次。 客戶端可以干的事 1. 輸入檢查 輸入檢查的邏輯,必須放在服務(wù)器端代碼中實(shí)現(xiàn)(因?yàn)橛肑avaScript做輸入檢查,很容易被攻擊者繞過(guò))。目前Web開(kāi)發(fā)的普遍做法,是同時(shí)在客戶端JavaScript中和服務(wù)器代碼中實(shí)現(xiàn)相同的輸入檢查。客戶端JavaScript的輸入檢查,可以阻擋大部分誤操作的正常用戶,從而節(jié)約服務(wù)資源。 PS:簡(jiǎn)單說(shuō),就是輸入檢查,服務(wù)端和客戶端都要做。 另外攻擊者可能輸入XSS的地方,例如: 1.頁(yè)面中所有的input框
2.window.location(href、hash等)
3.window.name
4.document.referrer
5.document.cookie
6.localstorage
7.XMLHttpRequest返回的數(shù)據(jù)
PS:當(dāng)然不止這些 2. 輸出檢查 一般就是在變量輸出到HTML頁(yè)面時(shí),使用編碼或轉(zhuǎn)義的方式來(lái)防御XSS攻擊。XSS的本質(zhì)就是“HTML注入”,用戶的數(shù)據(jù)被當(dāng)成了HTML代碼一部分來(lái)執(zhí)行,從而混淆了原本的語(yǔ)義,產(chǎn)生了新的語(yǔ)義。 觸發(fā)XSS的地方 1.document.write
2.xxx.innerHTML=
3.xxx.outerHTML=
4.innerHTML.replace
5.document.attachEvent
6.window.attachEvent
7.document.location.replace
8.document.location.assign
PS:如果使用jquery,就是那些append、html、before、after等,其實(shí)就是拼接變量到HTML頁(yè)面時(shí)產(chǎn)生。大部分的MVC框架在模板(view層)會(huì)自動(dòng)處理XSS問(wèn)題,例如AngularJS。 用什么編碼轉(zhuǎn)義 主要有HTMLEncode和JavaScriptEncode這兩個(gè),客戶端和服務(wù)端都能做。但是讓后端去做,我感覺(jué)是不大靠譜的,因?yàn)閿?shù)據(jù)的使用場(chǎng)景可能有幾種,可以在標(biāo)簽、屬性、或腳本里(甚至其他終端使用),單單以一種方式去encode是很極限的。 1.HTMLEncode,就是將字符轉(zhuǎn)換成HTMLEntities,一般會(huì)轉(zhuǎn)(&、<、>、"、''、/)這6個(gè)字符。 2.JavaScriptEncode,是使用”\“對(duì)特殊字符進(jìn)行轉(zhuǎn)義。 PS:我在《HtmlEncode和JavaScriptEncode(預(yù)防XSS)》一文總結(jié)了比較完整的HTMLEncode和JavaScriptEncode兩個(gè)前端函數(shù)的寫(xiě)法,以及一點(diǎn)示例。 哪些地方需要編轉(zhuǎn)義 1.在HTML標(biāo)簽、屬性中輸出——用HTMLEncode 2.在script標(biāo)簽中輸出——用JavaScriptEncode 3.在事件中輸出——用JavaScriptEncode <a href="#" onclick="funcA(''$var'')">test</a> 4.在CSS中輸出 用類(lèi)似JavaScriptEncode的方式。將除了字母、數(shù)字外的所有字符都編碼成十六進(jìn)制形式”\uHH“。 5.在地址中輸出 一般如果變量是整個(gè)URL,則先檢查變量是否以“http”開(kāi)頭(不是則幫忙添加http),保證不會(huì)出現(xiàn)偽協(xié)議類(lèi)的XSS攻擊。然后再對(duì)變量進(jìn)行URLEncode。 PS:URLEncode會(huì)將字符轉(zhuǎn)換成”%HH“形式。 總結(jié) 前端開(kāi)發(fā)人員要注意在正確的地方使用正確的編碼方式,有時(shí)為了防御XSS,在一個(gè)地方我們需要聯(lián)合HTMLEncode、JavaScriptEncode進(jìn)行編碼,甚至是疊加,并不是固定一種方式編碼(又是具體情況具體分析)。 一般存儲(chǔ)型XSS風(fēng)險(xiǎn)高于反射型XSS。反射型XSS一般要求攻擊者誘使用戶點(diǎn)擊一個(gè)包含XSS代碼的URL鏈接;而存儲(chǔ)型只需要用戶查看一個(gè)正常的URL鏈接,當(dāng)用戶打開(kāi)頁(yè)面時(shí),XSS Payload就會(huì)被執(zhí)行。這樣漏洞極其隱蔽,且埋伏在用戶的正常業(yè)務(wù)中,風(fēng)險(xiǎn)很高。(引自白帽子講Web安全原文) 本文為原創(chuàng)文章,轉(zhuǎn)載請(qǐng)保留原出處,方便溯源,如有錯(cuò)誤地方,謝謝指正。 本文地址 :http://www.cnblogs.com/lovesong/p/5223989.html 該文章在 2020/4/8 15:04:50 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |