[點晴永久免費OA]跨站腳本攻擊XSS案例及其解決方案
當(dāng)前位置:點晴教程→點晴OA辦公管理信息系統(tǒng)
→『 經(jīng)驗分享&問題答疑 』
跨站腳本攻擊XSS目錄 跨站腳本攻擊(Cross Site Script為了區(qū)別于CSS簡稱為XSS)指的是惡意攻擊者往Web頁面里插入惡意html代碼,當(dāng)用戶瀏覽該頁之時,嵌入其中Web里面的html代碼會被執(zhí)行,從而達到惡意用戶的特殊目的。 案例一:留言板的XSS攻擊我們有個頁面用于允許用戶發(fā)表留言,然后在頁面底部顯示留言列表
addElement()方法用于添加新的留言,而renderComments()方法用于展留言列表,網(wǎng)頁看起來是這樣的 XSS 因為我們完全信任了用戶輸入,但有些別有用心的用戶會像這樣的輸入 這樣無論是誰訪問這個頁面的時候控制臺都會輸出“Hey you are a fool fish!”,如果這只是個惡意的小玩笑,有些人做的事情就不可愛了,有些用戶會利用這個漏洞竊取用戶信息、誘騙人打開惡意網(wǎng)站或者下載惡意程序等,看個最簡單的例子
利用xss竊取用戶名密碼當(dāng)然這個示例很簡單,幾乎攻擊不到任何網(wǎng)站,僅僅看看其原理。我們知道很多登陸界面都有記住用戶名、密碼的功能方便用戶下次登錄,有些網(wǎng)站是直接用明文記錄用戶名、密碼,惡意用戶注冊賬戶登錄后使用簡單工具查看cookie結(jié)構(gòu)名稱后,如果網(wǎng)站有xss漏洞,那么簡單的利用jsonp就可以獲取其它用戶的用戶名、密碼了。 惡意用戶會這么輸入: 我們看看http://test.com/hack.js里藏了什么:
幾句簡單的javascript,獲取cookie中的用戶名密碼,利用jsonp把向 http://test.com/index.php 發(fā)送了一個get請求,來看一下http://test.com/index.php中的內(nèi)容:
這樣惡意用戶就把訪問留言板的用戶的信息竊取了。 案例二:輸入框的XSS攻擊有一個登錄頁面: 如果我有用戶abc,密碼123,輸入用戶名abc,密碼567,提示密碼錯誤,但是為了避免用戶再次輸入用戶名,將輸入的用戶名在頁面上保留。此時的html頁面是這樣的,按f12查看: 好,場景描述完畢,xss跨站腳本開始了: 1、如果我直接在用戶名這里輸入<script>alert("1")</script>,然后輸入一個錯誤的密碼,并沒有執(zhí)行script代碼,因為返回的html頁面是這樣的: 上圖中那樣的script代碼是不會執(zhí)行的,因為在input的value中,只有獨立的形如下的script代碼才會執(zhí)行。 所以要想實現(xiàn)script代碼的執(zhí)行,就需要進行拼接,將script代碼排到input標(biāo)簽外。 怎么實現(xiàn)呢? 說白了就是自己拼接,將input標(biāo)簽進行閉合,然后將script代碼綴在后邊。 通過用戶名的輸入,將input拼接成如下,即可實現(xiàn)script代碼的執(zhí)行: <input name="userName" class="textcss" id="userName" type="text" value="abc"/><script>alert("1")</script>"/> 為什么會執(zhí)行? 可以將拼接后的input拆分看一下,就很明白了 <input name="userName" class="textcss" id="userName" type="text" value="abc"/> <script>alert("1")</script> "/> 因為input已經(jīng)閉合了,所以script代碼會執(zhí)行,至于拼接后的html文件是有語法錯誤的問題(因為最后剩下一個"/>,這個html是有錯誤的,但是不影響頁面展示和script代碼執(zhí)行)就可以忽略了。 因此,只需要在用戶名那里輸入: abc"/><script>alert("1")</script> 然后輸入一個錯誤的密碼,點擊登錄,就會執(zhí)行script代碼,彈出彈框。
怎么預(yù)防服務(wù)端可以干的事1. HttpOnly 其實就是現(xiàn)在HTTP協(xié)議(HTTPS也是可以的)才能讀取cookies,JavaScript是讀取不到cookies的。支持瀏覽器是IE6+、Firefox2+、Google、Safari4+。 JavaEE給Cookie添加HttpOnly的代碼:
PS:對于HTTPS,還是可以設(shè)置Secure字段,對Cookie進行安全加密。 這是本質(zhì)上不是預(yù)防XSS,而是在被攻破時候不允許JS讀取Cookie。 2.處理富文本 有些數(shù)據(jù)因為使用場景問題,并不能直接在服務(wù)端進行轉(zhuǎn)義存儲。不過富文本數(shù)據(jù)語義是完整的HTML代碼,在輸出時也不會拼湊到某個標(biāo)簽的屬性中,所以可以當(dāng)特殊情況特殊處理。處理的過程是在服務(wù)端配置富文本標(biāo)簽和屬性的白名單,不允許出現(xiàn)其他標(biāo)簽或?qū)傩裕ɡ鐂cript、iframe、form等),即”XSS Filter“。然后在存儲之前進行過濾(過濾原理沒有去探明)。 Java有個開源項目Anti-Samy是非常好的XSS Filter:
PS:當(dāng)然也可以在前端顯示前過濾,但是我覺得,讓前端人員少做東西好,并且服務(wù)端只需要轉(zhuǎn)一次。
客戶端可以干的事1. 輸入檢查 輸入檢查的邏輯,必須放在服務(wù)器端代碼中實現(xiàn)(因為用JavaScript做輸入檢查,很容易被攻擊者繞過)。目前Web開發(fā)的普遍做法,是同時在客戶端JavaScript中和服務(wù)器代碼中實現(xiàn)相同的輸入檢查??蛻舳薐avaScript的輸入檢查,可以阻擋大部分誤操作的正常用戶,從而節(jié)約服務(wù)資源。 PS:簡單說,就是輸入檢查,服務(wù)端和客戶端都要做。 另外攻擊者可能輸入XSS的地方,例如: 1.頁面中所有的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頁面時,使用編碼或轉(zhuǎn)義的方式來防御XSS攻擊。XSS的本質(zhì)就是“HTML注入”,用戶的數(shù)據(jù)被當(dāng)成了HTML代碼一部分來執(zhí)行,從而混淆了原本的語義,產(chǎn)生了新的語義。 觸發(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等,其實就是拼接變量到HTML頁面時產(chǎn)生。大部分的MVC框架在模板(view層)會自動處理XSS問題,例如AngularJS。 用什么編碼轉(zhuǎn)義 主要有HTMLEncode和JavaScriptEncode這兩個,客戶端和服務(wù)端都能做。但是讓后端去做,我感覺是不大靠譜的,因為數(shù)據(jù)的使用場景可能有幾種,可以在標(biāo)簽、屬性、或腳本里(甚至其他終端使用),單單以一種方式去encode是很極限的。 1.HTMLEncode,就是將字符轉(zhuǎn)換成HTMLEntities,一般會轉(zhuǎn)(&、<、>、"、''、/)這6個字符。 2.JavaScriptEncode,是使用”\“對特殊字符進行轉(zhuǎn)義。 PS:我在《HtmlEncode和JavaScriptEncode(預(yù)防XSS)》一文總結(jié)了比較完整的HTMLEncode和JavaScriptEncode兩個前端函數(shù)的寫法,以及一點示例。 哪些地方需要編轉(zhuǎn)義 1.在HTML標(biāo)簽、屬性中輸出——用HTMLEncode 2.在script標(biāo)簽中輸出——用JavaScriptEncode 3.在事件中輸出——用JavaScriptEncode <a href="#" οnclick="funcA(''$var'')">test</a> 4.在CSS中輸出 用類似JavaScriptEncode的方式。將除了字母、數(shù)字外的所有字符都編碼成十六進制形式”\uHH“。 5.在地址中輸出 一般如果變量是整個URL,則先檢查變量是否以“http”開頭(不是則幫忙添加http),保證不會出現(xiàn)偽協(xié)議類的XSS攻擊。然后再對變量進行URLEncode。 PS:URLEncode會將字符轉(zhuǎn)換成”%HH“形式。 總結(jié) 前端開發(fā)人員要注意在正確的地方使用正確的編碼方式,有時為了防御XSS,在一個地方我們需要聯(lián)合HTMLEncode、JavaScriptEncode進行編碼,甚至是疊加,并不是固定一種方式編碼(又是具體情況具體分析)。 一般存儲型XSS風(fēng)險高于反射型XSS。反射型XSS一般要求攻擊者誘使用戶點擊一個包含XSS代碼的URL鏈接;而存儲型只需要用戶查看一個正常的URL鏈接,當(dāng)用戶打開頁面時,XSS Payload就會被執(zhí)行。這樣漏洞極其隱蔽,且埋伏在用戶的正常業(yè)務(wù)中,風(fēng)險很高。(引自白帽子講Web安全原文) 該文章在 2020/4/8 16:08:35 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |