日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

瀏覽器解析機制和XSS向量編碼

作者:喜樂有分享 更新時間: 2022-07-26 編程語言

xss編碼

解析不了

1.<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>
URL 編碼 "javascript:alert(1)",
2.<a href="javascript:%61%6c%65%72%74%28%32%29">
HTML字符實體編碼 "javascript" 和 URL 編碼 "alert(2)"
3.<a href="javascript%3aalert(3)"></a>
URL 編碼 ":"
4.<div><img src=x οnerrοr=alert(4)></div>
HTML字符實體編碼 < 和 >
5.<textarea><script>alert(5)</script></textarea>
HTML字符實體編碼 < 和 >
6.<textarea><script>alert(6)</script></textarea>


html解析

從XSS的角度來說,我們感興趣的是HTML文檔是如何被詞法解析的,因為我們并不想讓用戶提供的數據最終被解析為一段可執行腳本的script標簽。HTML詞法解析細則在這里。HTML詞法解析細則是一篇冗長的文檔,這篇博文并不會覆蓋它的所有內容。這篇博文只會覆蓋有關文檔解碼如何結束,以及新token何時被創建這兩個有趣的部分。<input value="dasdsad">dadasdsadadsa

一個HTML解析器作為一個狀態機,它從輸入流中獲取字符并按照轉換規則轉換到另一種狀態。在解析過程中,任何時候它只要遇到一個'<'符號(后面沒有跟'/'符號)就會進入“標簽開始狀態(Tag open state)”。然后轉變到“標簽名狀態(Tag name state)”,“前屬性名狀態(before attribute name state)”......最后進入“數據狀態(Data state)”并釋放當前標簽的token。當解析器處于“數據狀態(Data state)”時,它會繼續解析,每當發現一個完整的標簽,就會釋放出一個token。

(譯者注:詞法解析是《編譯原理》所涉及的內容,學習過編譯原理的讀者可以更好的理解“狀態機”的工作原理)。

這里有三種情況可以容納字符實體,“數據狀態中的字符引用”,“RCDATA狀態中的字符引用”和“屬性值狀態中的字符引用”。在這些狀態中HTML字符實體將會從“&#...”形式解碼,對應的解碼字符會被放入數據緩沖區中。例如,在問題4中,“<”和“>”字符被編碼為“&#60”和“&#62”。當解析器解析完“<div>”并處于“數據狀態”時,這兩個字符將會被解析。當解析器遇到“&”字符,它會知道這是“數據狀態的字符引用”,因此會消耗一個字符引用(例如“&#60”)并釋放出對應字符的token。在這個例子中,對應字符指的是“<”和“>”。讀者可能會想:這是不是意味著“<”和“>”的token將會被理解為標簽的開始和結束,然后其中的腳本會被執行?答案是腳本并不會被執行。原因是解析器在解析這個字符引用后不會轉換到“標簽開始狀態”。正因為如此,就不會建立新標簽。因此,我們能夠利用字符實體編碼這個行為來轉義用戶輸入的數據從而確保用戶輸入的數據只能被解析成“數據”。

字符實體(character entities)

字符實體是一個轉義序列,它定義了一般無法在文本內容中輸入的單個字符或符號。一個字符實體以一個&符號開始,后面跟著一個預定義的實體的名稱,或是一個#符號以及字符的十進制數字。

HTML字符實體(HTML character entities)

在HTML中,某些字符是預留的。例如在HTML中不能使用“<”或“>”,這是因為瀏覽器可能誤認為它們是標簽的開始或結束。如果希望正確地顯示預留字符,就需要在HTML中使用對應的字符實體。一個HTML字符實體描述如下:

需要注意的是,某些字符沒有實體名稱,但可以有實體編號。

字符引用(character references)

字符引用包括“字符值引用”和“字符實體引用”。在上述HTML例子中,'<'對應的字符值引用為'&#60',對應的字符實體引用為‘&lt’。字符實體引用也被叫做“實體引用”或“實體”。)

現在你大概會明白為什么我們要轉義“<”、“>”、“'” (單引號)和“"” (雙引號)字符了。

這里要提一下RCDATA的概念。要了解什么是RCDATA,我們先要了解另一個概念。在HTML中有五類元素:

  1. 空元素(Void elements),如<area>, ,<base>等等

  2. 原始文本元素(Raw text elements),有<script>和<style>

  3. RCDATA元素(RCDATA elements),有<textarea>和<title>

  4. 外部元素(Foreign elements),例如MathML命名空間或者SVG命名空間的元素

  5. 基本元素(Normal elements),即除了以上4種元素以外的元素

五類元素的區別如下:

  1. 空元素,不能容納任何內容(因為它們沒有閉合標簽,沒有內容能夠放在開始標簽和閉合標簽中間)。

  2. 原始文本元素,可以容納文本。

  3. RCDATA元素,可以容納文本和字符引用。

  4. 外部元素,可以容納文本、字符引用、CDATA段、其他元素和注釋

  5. 基本元素,可以容納文本、字符引用、其他元素和注釋

如果我們回頭看HTML解析器的規則,其中有一種可以容納字符引用的情況是“RCDATA狀態中的字符引用”。這意味著在<textarea>和<title>標簽中的字符引用會被HTML解析器解碼。這里要再提醒一次,在解析這些字符引用的過程中不會進入“標簽開始狀態”。這樣就可以解釋問題5了。另外,對RCDATA有個特殊的情況。在瀏覽器解析RCDATA元素的過程中,解析器會進入“RCDATA狀態”。在這個狀態中,如果遇到“<”字符,它會轉換到“RCDATA小于號狀態”。如果“<”字符后沒有緊跟著“/”和對應的標簽名,解析器會轉換回“RCDATA狀態”。這意味著在RCDATA元素標簽的內容中(例如<textarea>或<title>的內容中),唯一能夠被解析器認做是標簽的就是“</textarea>”或者“</title>”。因此,在“<textarea>”和“<title>”的內容中不會創建標簽,就不會有腳本能夠執行。這也就解釋了為什么問題6中的腳本不會被執行。


原文鏈接:https://blog.csdn.net/weixin_52159400/article/details/125984311

欄目分類
最近更新