XSS編碼與繞過 javascript
對於瞭解web安全的朋友來講,都知道XSS這種漏洞,其危害性不用強調了。通常對於該漏洞的防禦有兩個思路:一是過濾敏感字符,諸如【<,>,script,'】等,另外一種是對敏感字符進行html編碼,諸如php中的htmlspecialchars()函數。php
通常狀況,正確實施這兩種方案之一就能夠有效防護XSS漏洞了。但其實也會有一些場景,即便實施了這兩種方案,攻擊者也能夠繞過防禦,致使XSS漏洞被利用。html
下面主要是參考文章http://www.freebuf.com/articles/web/43285.html。java
場景一:XSS注入點在某個html標籤屬性中,代碼片斷以下git
能夠看到,這裏防禦措施採用的是方案一:過濾敏感字符。那麼這裏若是輸入javascript:alert (11),是會被過濾掉的,輸出的內容會是:github
這固然不能彈框,常規的xss payload就會失敗了。如同參考文中所說的,這裏繞過方法有不少中,你徹底不須要使用 > 去閉合html標籤,也能夠用其餘關鍵字來代替javascript,不過既然說的是編碼問題,固然要用編碼問題來解決問題。web
這裏能夠對"javascript:alert(11)"進行html編碼來繞過,你能夠試試將html編碼後的payload傳遞給name參數,也就是:javascript%3Aalert%2811%29,能夠看到熟悉的窗口又彈出來了。緣由就是,瀏覽器在解析到這段代碼時,會對其先進行html解碼,而後當觸發onclick事件後,會調用js引擎對其進行js編碼後執行js代碼,因此就看到了彈窗。原文在這裏只提到了html編碼的方式,其實這裏還能夠對payload進行js編碼。可是要注意的是,這裏不能將整個payload進行編碼,你要像這樣:express
又能夠看見彈框了。(是否是略微有點看不懂啊,不要緊,接下來還有更繞的)瀏覽器
場景二:XSS注入點在js標籤中,代碼片斷:安全
這裏採用的防禦措施是第二套,使用php內置函數htmlspecialchars對敏感字符進行編碼。若是輸入正常的payload,如:<img src=1 onerror=alert(11)>,是不會有彈窗的,此時瀏覽器的輸出:
這裏的敏感字符< >,已經被html編碼了,最後在<div>標籤裏面輸出的時候瀏覽器再使用html解碼將其原文顯示出來,可是並不會再觸發js引擎了,因此也就沒有彈窗了,利用失敗。
這裏使用js編碼就能夠繞過了,由於瀏覽器是先js解碼而後再html解碼,經過js編碼後的payload在html解碼的時候已是正常的html了,就會觸發js引擎,彈框也就出來了。
試試js編碼後的payload:
看到這裏,你心中確定有疑問,瀏覽器究竟是怎麼解碼的,爲何一會先js解碼,一下子又是先html解碼?起初我在看到這裏時候也一直很納悶,原文裏面並無對瀏覽器爲何這樣解碼說明緣由,直到我看到這篇文章http://xuelinf.github.io/2016/05/18/編碼與解碼-瀏覽器作了什麼/。該做者從原理上對瀏覽器編碼解碼進行了說明,揭開了個人疑問,這篇文章也主要是說明該問題。
來看看瀏覽器處理一次完整的http請求,會涉及到的編碼解碼問題。
以上,就是瀏覽器解析一次完整http請求所會涉及到的編碼解碼問題。瀏覽器在收到html文件後,若是沒有js DOM API的參與,那麼瀏覽器會按照html解碼àCSS解碼àjs解碼的順序解析下去,可是因爲js DOM API的存在,解碼順利會被打亂,因此有了上面兩個場景中不一樣的解碼順序,那麼到底爲什麼要按照這樣的解碼方式呢?再來具體看看js解釋器的處理流程。
當瀏覽器在處理諸如<script> <style>標籤,解釋器會自動切換到特殊解析模式,src href後邊加入的javascript爲URL,也會進入到JS解析模式。而進入該解析模式的時候,該DOM節點已經創建起來了,可是html解釋器還並未進行html解碼。當觸發js解釋器後,js會先對內容進行解析,若是有js編碼就會進行解碼操做,接下來是就是執行裏面的js語句。因此此時執行該js語言前的解碼順序爲js解碼-->html解碼。
來看看可以觸發js引擎的標籤:
既然js DOM API能夠更改瀏覽器正常的解碼順序,那麼觸發js解釋器的方式有哪些呢?
瞭解了瀏覽器的編碼解碼以後,咱們再回頭看一下前面的兩個場景。
第一個場景中,js語句是在a標籤中,在onclick事件觸發js解釋器以前,DOM樹結構已經創建完成了,而且這裏也沒有DOM API操做,因此瀏覽器會先對該語句進行html解碼,而後再是js解碼,因此當咱們對payload進行html編碼後,在js解釋器解析該js語句時,其已經被html解碼了,是正常的js語句,因此可以正常彈窗。
場景二中,payload是在script標籤裏面,瀏覽器解析到這裏時,會觸發js解釋器,js解釋器會對該語句進行js解碼操做,咱們使用js編碼的payload被還原成正常的語句。雖然此時整個DOM樹已經創建起來了,可是因爲DOM API存在,會再一次的調用html解釋器,對咱們的payload進行解析,payload裏面有js標籤,再一次觸發js解釋器,完成對js語句調用,成功彈窗。
能夠看到,由於瀏覽器豐富多樣的解碼方式,對於XSS的防護不能徹底單一依靠編碼和過濾操做,須要根據上下文對輸入語句,先進行相應的解碼以後再進行編碼和過濾操做,纔能有效的防護XSS。
by:會飛的貓