XSS的那些事儿
轉(zhuǎn)載自?XSS的那些事兒
XSS是什么
XSS,Cross-site scripting,跨站腳本攻擊,為了區(qū)分與CSS,起名為XSS。黑客利用網(wǎng)站的漏洞,通過(guò)代碼注入的方式將一些包含了惡意攻擊腳本程序注入到網(wǎng)頁(yè)中,企圖在用戶(hù)加載網(wǎng)頁(yè)時(shí)執(zhí)行腳本來(lái)實(shí)施攻擊。腳本程序通常是JavaScript編寫(xiě),當(dāng)然還包括Java,VBScript,ActiveX等。常見(jiàn)的攻擊手段是獲取用戶(hù)身份認(rèn)證信息(Cookie,Session)、獲取私密網(wǎng)頁(yè)內(nèi)容、植入病毒等。
XSS漏洞可以追溯到1990年代。Twitter,Facebook,MySpace,Orkut,新浪微博和百度貼吧這些網(wǎng)站曾遭受XSS漏洞攻擊或被發(fā)現(xiàn)此類(lèi)漏洞。而最近幾年XSS升級(jí)為最流行的攻擊方式,有68%的網(wǎng)站可能遭受此類(lèi)攻擊。根據(jù)開(kāi)放網(wǎng)頁(yè)應(yīng)用安全計(jì)劃(Open Web Application Security Project)公布的2010年統(tǒng)計(jì)數(shù)據(jù),在Web安全威脅前10位中,XSS排在第2位,僅次于代碼注入。
場(chǎng)景還原
XSS是之所以能成功在于黑客注入的腳本程序在網(wǎng)頁(yè)上得到執(zhí)行,那么它是怎么被注入?又是如何被執(zhí)行的?我們來(lái)躺槍一次XSS攻擊就知道怎么回事了。
忙碌的一天過(guò)去了,下班后我打開(kāi)博客,準(zhǔn)備寫(xiě)篇《XSS的那些事兒》。于是乎我偷偷的在內(nèi)容處寫(xiě)入了以下代碼:
提交發(fā)布博客后,我查看網(wǎng)頁(yè)的博客內(nèi)容,頁(yè)面刷新時(shí),就會(huì)彈出一個(gè)對(duì)話(huà)框:
之所以會(huì)彈出這個(gè)對(duì)話(huà)框,是因?yàn)槲覄倢?xiě)在內(nèi)容中的那行JavaScript代碼被執(zhí)行了(注入的代碼被執(zhí)行)。我嘗試把這行代碼push到GitHub Page博客的Repository上,我就會(huì)遇到這種問(wèn)題。它只是一句簡(jiǎn)單的警告彈框,用戶(hù)登錄后的網(wǎng)站中嵌入下面代碼又會(huì)發(fā)生什么呢:
? ? var cockie = window.cockie; // localStorage, sessionStorage
? ? // Send cockie|localStorage|sessionStorage information to hacker
</script>
如果我訪問(wèn)的博客網(wǎng)站使用了JWT做用戶(hù)認(rèn)證,將Token保存在sessionStorage(cookie或 localStorage)中,而我無(wú)意間訪問(wèn)了一個(gè)包含上述腳本的網(wǎng)頁(yè),我的身份認(rèn)證信息就會(huì)被黑客竊取,后續(xù)的事情就不得而知了。
XSS家族體系
根據(jù)XSS的表現(xiàn)形式和存儲(chǔ)形態(tài),XSS主要分為三類(lèi)反射性、持久型和基于DOM三種類(lèi)型。而基于DOM型和反射型本質(zhì)上又是一種類(lèi)型。
反射型
XSS攻擊最開(kāi)始出現(xiàn)是在那種服務(wù)器負(fù)責(zé)處理所有數(shù)據(jù)的網(wǎng)站中。比如一個(gè)Servlet+JSP的網(wǎng)站,服務(wù)器在處理完用戶(hù)的輸入(包含XSS)之后會(huì)將結(jié)果作為一個(gè)頁(yè)面(包含XSS)返回給用戶(hù),XSS就會(huì)立即被執(zhí)行,該類(lèi)型就是典型的反射型XSS。
反射性是XSS中最基本的攻擊,用戶(hù)輸入(包含XSS)通常附加在HTTP查詢(xún)參數(shù)或者表單上,提交請(qǐng)求后,服務(wù)器直接返回結(jié)果就立即執(zhí)行執(zhí)行XSS。
反射型的攻擊主要針對(duì)個(gè)人用戶(hù)。黑客通常通過(guò)郵件發(fā)送包含一些看似沒(méi)有問(wèn)題的URL(誘餌)給用戶(hù),用戶(hù)點(diǎn)擊這些URL后就會(huì)跳轉(zhuǎn)到一個(gè)隱藏著XSS攻擊的網(wǎng)站。
持久型
我們知道反射型XSS需要使用誘惑用戶(hù)針對(duì)的是個(gè)人用戶(hù),它的危害和波及范圍是可控的。而XSS被持久化到服務(wù)器數(shù)據(jù)庫(kù)中后,影響范圍就不再可控了。來(lái)回顧前文獲取cookie的XSS腳本:
? ? var cockie = window.cockie; // localStorage, sessionStorage
? ? // Send cockie|localStorage|sessionStorage information to hacker
</script>
如果該腳本被作為一篇博客文章的內(nèi)容被原樣持久化到服務(wù)器端的數(shù)據(jù)庫(kù)中,之后任何用戶(hù)在瀏覽該博客文章的時(shí)候都會(huì)觸發(fā)瀏覽器執(zhí)行該腳本,用戶(hù)的身份信息便會(huì)被盜走。
這種持久化在服務(wù)器端的XSS就是一種持久型的XSS攻擊,它的影響范圍是很廣。因?yàn)橐坏┍怀志没椒?wù)器,該博客網(wǎng)站的任何用戶(hù)都有可能遭遇攻擊。
基于DOM
隨著Web的發(fā)展,頁(yè)面承載了越來(lái)越多的展現(xiàn)邏輯,那么為了提高用戶(hù)體驗(yàn),頁(yè)面的渲染由同步轉(zhuǎn)向異步,架構(gòu)師開(kāi)始采用JavaScript+AJAX的方案。之后JavaScript就逐漸掌管頁(yè)面中數(shù)據(jù)請(qǐng)求和邏輯渲染。
JavaScript同時(shí)會(huì)處理用戶(hù)輸入并將其渲染出來(lái)。如果用戶(hù)輸入包含了XSS,此時(shí)XSS會(huì)以DOM的形式被執(zhí)行。而這種XSS攻擊我們稱(chēng)之為基于DOM型。
基于DOM型是由反射型衍生出來(lái)的一種新的類(lèi)型,不同于反射型的是,后者需要服務(wù)器端的反射,而前者不會(huì)涉及跟服務(wù)器的交互。但它們本質(zhì)上是一種類(lèi)型,只是因?yàn)橄到y(tǒng)架構(gòu)的演變而不得不進(jìn)行基因變異。
防御措施
當(dāng)我們使用cookie的時(shí)候,我們要防范CSRF,當(dāng)我們使用了Token的時(shí)候,我們又得防范XSS,有種Web世界太危險(xiǎn),我要轉(zhuǎn)后端(服務(wù)器端)開(kāi)發(fā)的姿態(tài)。不巧的是,恰恰從服務(wù)器端去阻止XSS攻擊才是有效的途徑。
從XSS的家族體系中可以看出XSS其實(shí)就是用戶(hù)輸入寄生蟲(chóng),所以只要能對(duì)癥下藥,正確處理用戶(hù)輸入,就能防御絕大部分XSS攻擊,甚至使其無(wú)地容身。
雙重校驗(yàn)
對(duì)于用戶(hù)輸入,我們始終要保持懷疑的態(tài)度。要消除這種懷疑,我們要在瀏覽器端和服務(wù)器端做雙重嚴(yán)格校驗(yàn)。
在安全架構(gòu)方面,我們對(duì)JavaScript的定位是僅用于提高用戶(hù)體驗(yàn)。所以瀏覽器校驗(yàn)只是用來(lái)防君子,根本上需要在服務(wù)器端搭設(shè)一層可靠的防御網(wǎng)。針對(duì)雙重校驗(yàn),我們可以的事情主要有:
1.嚴(yán)格控制輸入的格式,比如年齡的input中,只允許用戶(hù)輸入數(shù)字。 2.對(duì)數(shù)據(jù)進(jìn)行HTMLEncode處理,對(duì)URL進(jìn)行URLEncode。3.過(guò)濾或移除特殊的HTML標(biāo)簽。例如: <script>,<iframe>,<?
for <,>for >, " for等。
4.過(guò)濾JavaScript事件的標(biāo)簽。例如"οnclick=","onfocus"等
Web Framework在這方面一般都集成了XSS防御功能,比如Spring Security就提供了配置http.headers().xssProtection()的選項(xiàng)。
注入猴子
當(dāng)我們處在危險(xiǎn)境遇,我們不能坐以待斃。提前做一些主動(dòng)的安全防御措施是絕對(duì)有必要的。比如說(shuō)引入一些自動(dòng)化的XSS監(jiān)測(cè)機(jī)制。
借鑒著名的Netflix猴子軍的做法:
混亂猴子(Chaos Monkey):
負(fù)責(zé)在一天隨機(jī)停掉服務(wù)器。
混亂大猩猩(Chaos Gorilla):
負(fù)責(zé)隨機(jī)關(guān)閉整個(gè)可用區(qū)(數(shù)據(jù)中心)。
延遲猴子(Latency Monkey):
則負(fù)責(zé)下系統(tǒng)之間注入網(wǎng)絡(luò)延遲。
Netflix的猴子軍的目標(biāo)是在生產(chǎn)環(huán)境的制造故障,來(lái)鍛煉團(tuán)隊(duì)對(duì)故障的應(yīng)對(duì)能力。它核心理念:從錯(cuò)誤中學(xué)習(xí)成長(zhǎng)。所以我們既然要防御XSS,不妨引入一直注入猴子(Injectiion Monkey),它主要負(fù)責(zé)向我們的網(wǎng)站中注入類(lèi)似腳本:
<script>alert(document.cookie)</script><!--
"onclick="alert(document.cookie)
特殊保護(hù)
XSS通常會(huì)盜用用戶(hù)身份信息,如果網(wǎng)站使用了Cookie中保存用戶(hù)Session的機(jī)制,則需要將重要的Cookie設(shè)置為httponly,即不讓JavaScript腳本去讀取Cooike信息。使用這種機(jī)制需要防范CSRF攻擊。如果你的網(wǎng)站使用了Token機(jī)制,則需要重點(diǎn)實(shí)施上述兩條措施。
總結(jié)
- 上一篇: Spring Boot面试题
- 下一篇: JAVA面试常考系列一