html中alert的用法_【渗透实战】通过HTML命名空间混淆绕过DOMPurify实现XSS
我們首先了解下DOMPurify通常是如何使用的。假設(shè)我們需要將html Markup中一個(gè)不受信任的HTML賦值給某個(gè)div,我們可以通過以下代碼使用DOMPurify對該內(nèi)容進(jìn)行過濾,在賦值給div:
div.innerHTML = DOMPurify.sanitize(htmlMarkup)在解析、系列化以及處理DOM樹的過程中,上訴代碼實(shí)際上會(huì)執(zhí)行以下操作:
htmlMarkup被解析為DOM樹
DOMPurify過濾DOM樹(簡而言之,這個(gè)過程中DOMPurify會(huì)遍歷DOM樹中的所有元素以及屬性,并刪除不在允許列表中的所有節(jié)點(diǎn))
DOM樹被序列化回HTML標(biāo)記
賦值給innerHTML之后,瀏覽器將再次解析HTML標(biāo)記
解析的DOM樹被附加到文檔的DOM樹中
這就是DOMPurify.sanitize返回的結(jié)果。然后瀏覽器在賦值給innerHTML時(shí)會(huì)再次解析該標(biāo)記。
DOM樹與DOMPurify處理過的樹相同,然后將其附加到目標(biāo)文檔中。
簡而言之,按順序,以上過程可以總結(jié)成:解析->序列化->解析。直觀上,大家可能會(huì)覺得系列化DOM樹,并再次解析后,應(yīng)該會(huì)返回初始的DOM樹,但事實(shí)并非如此。
HTML規(guī)范中,關(guān)于系列化HTML片段的警告信息表明:如果使用HTML解析器進(jìn)行解析,則此算法[序列化HTML]的輸出可能不會(huì)返回初始的樹結(jié)構(gòu)。HTML解析器本身也有可能輸出不往返序列化和重新解析步驟的樹結(jié)構(gòu),盡管這種情況通常不符合要求。
值得注意的是,序列號-重新解析的往返操作并不一定能返回初始的DOM樹,這也是造成mutation XSS(突變XSS) 的根本原因。通常這類情況是由于某些解析器、序列化器錯(cuò)誤所導(dǎo)致的結(jié)果,但有兩種特殊情況符合上訴警告信息所描述的場景。
3嵌套FORM元素其中一種情況涉及FORM元素,它是HTML里非常特殊的一個(gè)元素,因?yàn)樗旧聿荒芮短住TML規(guī)范中,明確指出FORM元素不可以是某個(gè)FORM元素的后繼。
可以在任何瀏覽器中使用以下標(biāo)記進(jìn)行驗(yàn)證:
<form id=form1>INSIDE_FORM1<form id=form2>INSIDE_FORM2該片段會(huì)生成以下DOM樹:
第2個(gè)form在DOM樹中會(huì)被完全忽略,就像從未存在過一樣。
接下來是比較有趣的部分。如果我們繼續(xù)閱讀HTML規(guī)范,會(huì)發(fā)現(xiàn)它實(shí)際上給出了一個(gè)示例,該示例通過帶有錯(cuò)誤嵌套標(biāo)簽的標(biāo)記成功創(chuàng)建了一個(gè)嵌套式表單。如下所示:
<form id="outer"><div>form><form id="inner"><input>結(jié)果會(huì)生成以下包含一個(gè)嵌套表單元素的DOM樹:
這并不是特定瀏覽器的bug,它直接來自HTML規(guī)范,并且在解析HTML的算法中也有描述。大意如下所示:
當(dāng)我們打開標(biāo)簽時(shí),解析器需要記錄該標(biāo)簽是由表單元素指針打開的。如果指針不為空,則無法創(chuàng)建表單元素。
當(dāng)我們結(jié)束標(biāo)簽時(shí),表單元素指針始終設(shè)置為null。
因此,回到以下片段:
<form id="outer"><div>form><form id="inner"><input>首先,表單元素指針設(shè)置為id =“outer”,然后開始解析div,碰到閉合標(biāo)簽后,表單元素指針會(huì)被設(shè)置為null。由于指針為null,因此可以創(chuàng)建下一個(gè)id=“ inner”的表單。并且由于我們當(dāng)前位于div內(nèi),因此可以成功創(chuàng)建一個(gè)嵌套式表單。
現(xiàn)在,如果我們嘗試序列化生成的DOM樹,將獲得以下標(biāo)記:
<form id="outer"><div><form id="inner"><input>form>div>form>值得注意的是,該標(biāo)記將不包含任何錯(cuò)誤嵌套的標(biāo)簽。當(dāng)再次解析標(biāo)記時(shí),將創(chuàng)建以下DOM樹:
綜上,我們證明了經(jīng)過序列化、重解析后并不一定能返回原始的DOM樹。更有趣的是,這基本上是一種符合規(guī)范的突變。
當(dāng)我發(fā)現(xiàn)這一點(diǎn)后,便意識到可以通過某種方式濫用這種特性以繞過HTML過濾器。思考了很久后,偶然間發(fā)現(xiàn)HTML規(guī)范中的另一個(gè)異常點(diǎn)。在繼續(xù)討論該問題前,我們先來了解下HTML規(guī)范中的潘多拉魔盒:外部內(nèi)容(foreign content)。
4外部內(nèi)容外部內(nèi)容就好比一把瑞士軍刀,可以用來破壞解析器及過濾器。該方法曾被我用來繞過DOMPurify以及Ruby過濾庫。
HTML解析器可以使用三個(gè)命名空間元素創(chuàng)建DOM樹:?
HTML命名空間(http://www.w3.org/1999/xhtml)?
SVG命名空間(http://www.w3.org/2000/svg)?
MathML命名空間(http://www.w3.org/1998/Math/MathML)?
默認(rèn)情況下,所有元素都位于HTML命名空間中。但是,如果解析器遇到或元素,則它將分別“切換”到SVG和MathML命名空間。這兩個(gè)命名空間都會(huì)產(chǎn)生外部內(nèi)容。
在外部內(nèi)容中,標(biāo)記的解析過程與普通的HTML不同。尤其是在解析
思考以下標(biāo)記:
它將被解析成以下DOM樹:
備注:從現(xiàn)在開始,本文DOM樹中的所有元素都將包含一個(gè)命名空間。因此html style意味著它是HTML命名空間中的
最終的DOM樹證實(shí)我的觀點(diǎn):html style僅包含文本內(nèi)容,而svg style會(huì)像普通元素一樣被解析。?
繼續(xù)分析,我們可能會(huì)猜想:如果我們位于或內(nèi)部,則所有元素也都會(huì)位于非HTML命名空間中。但事實(shí)并非如此,HTML規(guī)范中包含MathML文本集成點(diǎn)和HTML集成點(diǎn),這些元素的子元素都具有HTML命名空間(但某些情況除外)。?
思考以下示例:
它將被解析成以下DOM樹
請注意觀察,在MathML命名空間中,style元素是如何成為math的直接子元素的,而mtext中的style元素則位于HTML命名空間中。這是因?yàn)閙text是MathML文本集成點(diǎn),并使用解析器切換命名空間。
MathML文本集成點(diǎn)包括:
math mi
math mo
math mn
math ms
HTML集成點(diǎn)包括:
math annotation-xml(如果其具有encoding屬性,并且屬性值等于text/html或者application/xhtml+xml)
svg foreignObject
svg desc
svg title
我之前一直以為MathML文本集成點(diǎn)或HTML集成點(diǎn)的所有子級,默認(rèn)情況下都具有HTML命名空間,但事實(shí)并非如此。HTML規(guī)范指出,默認(rèn)情況下,MathML文本集成點(diǎn)的子級都位于HTML命名空間中。但有兩種例外情況:mglyph和malignmark。只有當(dāng)它們是MathML文本集成點(diǎn)的直接子級時(shí),才會(huì)發(fā)生這種情況。
我們可以通過以下標(biāo)記進(jìn)行檢查:
注意,作為mtext的直接子元素的mglyph在MathML命名空間中,而作為html元素的子元素的mglyph在HTML命名空間中。
假設(shè)我們想確定一個(gè)“當(dāng)前元素”的命名空間。此時(shí)我已經(jīng)制定了一些經(jīng)驗(yàn)法則:
除非滿足以下條件,否則當(dāng)前元素將位于其父元素的命名空間中。
如果當(dāng)前元素為或,且其父元素在HTML命名空間中,則當(dāng)前元素分別位于SVG或MathML命名空間中。?
如果當(dāng)前元素的父元素是HTML集成點(diǎn),則當(dāng)前元素位于HTML命名空間中,除非它是或。?
如果當(dāng)前元素的父元素是MathML集成點(diǎn),則當(dāng)前元素位于HTML命名空間中,除非它是,,或。
如果當(dāng)前元素是,,
,,
,,,,,,, ,,,
,
,
,
,
,,,,,
- ,,,,,,
,
,,,,或,并定義了color,face或size屬性,那么堆棧上的所有元素將關(guān)閉,直到看到MathML文本集成點(diǎn)、HTML集成點(diǎn)或HTML命名空間中的元素為止。然后,當(dāng)前元素也會(huì)位于HTML命名空間中。
5
DOMPurify繞過
DOMPurify的典型使用方法致使HTML標(biāo)記被解析兩次。
HTML規(guī)范中存在特殊情況,可以創(chuàng)建嵌套form元素。但是,在重新解析時(shí),第二個(gè)form會(huì)被忽略。
mglyph和malignmark是HTML規(guī)范中的特殊元素,即使默認(rèn)情況下其他所有標(biāo)簽都位于HTML命名空間中,但如果它們是MathML文本集成點(diǎn)的直接子元素,那么它們也將位于MathML命名空間中。
結(jié)合以上幾點(diǎn),我們可以創(chuàng)建一個(gè)具有兩個(gè)form元素和mglyph元素的標(biāo)記,這些標(biāo)記最初位于HTML命名空間中,但是在重新解析時(shí)位于MathML命名空間中,從而使后續(xù)的style標(biāo)簽的解析方式有所不同,導(dǎo)致XSS。
end
總結(jié)
以上是生活随笔為你收集整理的html中alert的用法_【渗透实战】通过HTML命名空间混淆绕过DOMPurify实现XSS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: it项目经理带一个项目的完整_如何控制I
- 下一篇: 先查询再插入的存储过程怎么写_谈一谈 I