一.編碼解碼發(fā)生順序
瀏覽器最早開始解析HTML买猖,將標簽轉(zhuǎn)化為內(nèi)容樹中的DOM 節(jié)點婆赠,此時識別標簽的時候,HTML 解析器是無法識別哪些被實體編碼的內(nèi)容的得问,只有建立起DOM 樹,才能對每個節(jié)點的內(nèi)容進行識別软免,如果出現(xiàn)實體編碼,則會進行實體解碼焚挠。
基本的解析順序是這樣的膏萧,URL 解析器,HTML 解析器蝌衔, CSS 解析器榛泛,JS解析器,
(服務(wù)器)URL解析:例如input 內(nèi)容參數(shù)為:%26lt%5cu4e00%26gt
該值構(gòu)造在URL 里噩斟,瀏覽器直接發(fā)送給服務(wù)器曹锨,服務(wù)器接收之后,先進行URL 解析剃允,看到了% 這個符號沛简,于是URL 解碼,input 內(nèi)容變成了<\u4e00>
1.HTML解析(&#dex斥废,&#xhex.只要是DOM節(jié)點里屬性的值椒楣,都可以被HTML編碼和解析)
瀏覽器接收到頁面數(shù)據(jù),于是開始進行HTML 解析牡肉,構(gòu)造DOM樹捧灰。
所以,HTML 的分析器只能識別特定的詞法規(guī)則统锤,才能構(gòu)建起DOM 樹毛俏,這一塊,HTML 不會做解碼的工作饲窿,因為它做不了煌寇。所以,試圖這樣構(gòu)造利用漏洞免绿,是不可能的:
HTMl 解析器構(gòu)建DOM Tree,在DOM 樹構(gòu)建完畢之后唧席,這些HTML 實體編碼的內(nèi)容就會被解碼,如果識別為實體編碼的,會透明的解碼淌哟,于是:
例如:
會解析為:
2.CSS解析(CSS的屬性和值都可以進行CSS編碼和解析迹卢,冒號:不可以)
CSS 解析器并不會等到所有的html都解析完成之后再去構(gòu)建和布局render樹。它是解析完一部分內(nèi)容就顯示一部分內(nèi)容徒仓,同時腐碱,可能還在通過網(wǎng)絡(luò)下載其余內(nèi)容。
CSS 編碼解析是用了一套不太正統(tǒng)的轉(zhuǎn)義策略:用一個反斜杠掉弛,后邊跟1~6位十六進制數(shù)字構(gòu)成症见。,所以字母e 可以編碼為 \65, \065,\000065殃饿。而因為這樣谋作,后邊就不能直接緊跟數(shù)字或字母,否則會被當(dāng)成轉(zhuǎn)義里的內(nèi)容處理乎芳,所以CSS 選擇了空格作為終止標識遵蚜,在解碼的時候,再將空格去除奈惑。
3.JS解析(\uxxxx)只支持UNICODE
3.JS解析(\uxxxx)只支持UNICODE
在處理諸如< script> < style> 這樣的標簽吭净,解析器會自動切換到特殊解析模式,而src href 后邊加入的JavaScript 偽URL肴甸,也會進入JS 的解析模式寂殉。而進入該解析模式的時候,該DOM節(jié)點已經(jīng)建立起來了原在。
還是上邊的例子友扰,經(jīng)過HTML 的解碼,代碼已經(jīng)變成這樣:
href="javascript:alert('<\u4e00>')">test
javascript 出發(fā)了JS 解釋器晤斩,JS會先對內(nèi)容進行解析焕檬,里邊有一個轉(zhuǎn)義字符\u4e00,前導(dǎo)的 \u 表示他是一個Unicode 字符,根據(jù)后邊的數(shù)字澳泵,解析為'一'实愚,于是在完成JS的解析之后變成了:
href="javascript:alert('<一>')">test
然后JS 解釋器執(zhí)行alert("<一>"),這句話會交給瀏覽器渲染兔辅,最終彈窗腊敲。
轉(zhuǎn)義編碼應(yīng)當(dāng)只出現(xiàn)在標示符部分,不能用于對語法有真正影響的符號维苔,也就是括號碰辅,或者是引號。(不包含使用DOM操作的情況),DOM操作中括號和引號可以進行JS轉(zhuǎn)義介时。
在一個頁面中没宾,可以觸發(fā)JS 解析器的方式有這么幾種:
直接嵌入< script> 代碼塊凌彬。
javascript:xxx
通過< script sr=... > 加載代碼。
各種HTML CSS 參數(shù)支持JavaScript:URL 觸發(fā)調(diào)用循衰。
CSS expression(...) 語法和某些瀏覽器的XBL 綁定铲敛。
事件處理器(Event handlers),比如 onload, onerror, onclick等等。
定時器会钝,Timer(setTimeout, setInterval)
eval(...) 調(diào)用伐蒋。
4.DOM操作
在進行DOM操作時,會觸發(fā)JS解析器迁酸,例如:
document.getElementById("pic1").innerHTML = "";?
DOM 操作實際上是js強勢介入 HTML 和CSS 的結(jié)果先鱼,導(dǎo)致HTML標簽的屬性和值都可以做JS編碼和解析。