HTML5跨域消息發(fā)送安全性分析
HTML5是下一代的Web應(yīng)用,它具有許多新的特性,是一種新興的技術(shù)并且在移動(dòng)應(yīng)用中也有著廣泛的使用。但也正是因?yàn)樗囊恍┬绿匦缘某霈F(xiàn)以及廣泛的應(yīng)用,使得其安全性非常值得關(guān)注。
在本文中,我們將針對(duì)HTML5 Web消息發(fā)送(跨域消息發(fā)送)的安全性進(jìn)行分析和研究。
跨域消息發(fā)送
在討論這一問(wèn)題之前,我們先來(lái)了解下在HTML5中是如何實(shí)現(xiàn)跨域的消息發(fā)送。
在HTML5之前,由于同源策略的限制導(dǎo)致在兩個(gè)窗口之間進(jìn)行消息傳送必須是使用相同的協(xié)議、端口和主機(jī)。
HTML5有一種新的方法叫做postMessage(),通過(guò)這一方法,跨域的消息傳送將不再受到同源策略的限制。
以下是postMessage()的語(yǔ)法:
發(fā)送窗口:
Otherwindows:涉及到的其他窗口
Message:被發(fā)送到接收窗口的信息
targetOrigin:接收窗口必須規(guī)定的URL。如果沒(méi)有任何特殊偏好,可以將其規(guī)定為“*”定義“*”為targetOrigin,但這樣做其實(shí)會(huì)存在一些安全隱患,在后文中我會(huì)提到。
Transfer:這個(gè)是任意的。
接收窗口:
當(dāng)otherWindow.postMessage()執(zhí)行時(shí),消息將會(huì)被發(fā)送到接收窗口。
發(fā)送方使用以下這段代碼后,我們就可以接收到這條消息。
通過(guò)該段代碼,我們可以訪問(wèn)數(shù)據(jù)以及這一信息的源。如下所示:
Event.origin:提供信息的源(我們所接收到的信息的URL)
Event.data:提供實(shí)際所發(fā)送出的信息內(nèi)容#p#
安全性實(shí)例分析
出于演示需要,我設(shè)立了如下兩個(gè)Lab:
A: http://localhost:8383/
B: http://localhost/
正如你所看到的,上面兩個(gè)URL具有不同的端口,第一個(gè)運(yùn)行在8383端口,第二個(gè)則是在80端口。正是因?yàn)槠湓床煌圆艑?dǎo)致端口不同。
A是發(fā)送窗口,B是接收窗口
現(xiàn)在我們加載第二個(gè)URL(http://localhost/ )作為第一個(gè)URL的iframe:
通過(guò)使用postMessage()的方法,我可以輕松的將消息從第一個(gè)URL發(fā)送到第二個(gè)URL.
我們可以通過(guò)點(diǎn)擊”send message“的按鈕來(lái)進(jìn)行驗(yàn)證。
盡管加載在第一個(gè)URL中的iframe與其并不同源,但通過(guò)postMessage() 即可進(jìn)行信息傳遞。
現(xiàn)在我們來(lái)看一些postMessage()使用過(guò)程中可導(dǎo)致應(yīng)用出現(xiàn)漏洞的例子:
case1.
發(fā)送方代碼:
當(dāng)發(fā)送者把targetOrigin規(guī)定為通配符”*“時(shí),將會(huì)導(dǎo)致未知的信息被陌生的接收方(窗口)接收到。原因是從接收窗口傳來(lái)的消息任何人都可以再加載一個(gè)iframe來(lái)進(jìn)行監(jiān)聽(tīng)。因此在進(jìn)行敏感數(shù)據(jù)的傳輸時(shí),使用通配符是一個(gè)十分錯(cuò)誤的決定。
針對(duì)此問(wèn)題最好的解決方法就是在發(fā)送時(shí)添加具體的目標(biāo)字段,如下所示:
Case2.
接收窗口代碼:
在上面這段代碼中可以看到,我們是直接接收發(fā)送方的消息對(duì)其進(jìn)行處理,并不檢驗(yàn)是否來(lái)自發(fā)送方。
但檢查消息的來(lái)源無(wú)疑是十分重要的,這樣可以防止消息來(lái)自未經(jīng)授權(quán)的發(fā)送者。
因此,我們只需要在代碼中加入對(duì)發(fā)送方的驗(yàn)證,這一問(wèn)題就可解決了。代碼如下:
通過(guò)檢驗(yàn)event.origin,來(lái)進(jìn)行驗(yàn)證。
Case3.
在這一過(guò)程中,發(fā)送方和接收方都應(yīng)該驗(yàn)證正在傳送的.消息。如果數(shù)據(jù)插入到HTML DOM中時(shí)并沒(méi)有進(jìn)行驗(yàn)證,那么應(yīng)用很有可能遭受到基于DOM的跨站腳本攻擊。
由下面這段代碼可以看出,當(dāng)應(yīng)用程序接收到攻擊者發(fā)來(lái)的惡意信息,并已經(jīng)插入到HTML DOM使用innerHTML屬性時(shí),其顯得異常脆弱。
發(fā)送方:
接收方:
執(zhí)行上面這段代碼,可導(dǎo)致在接收窗口出現(xiàn)XSS。
解決這一問(wèn)題最簡(jiǎn)單的方法就是在給元素分配數(shù)據(jù)值時(shí)使用 textContent 而不是innerHTML.
如下所示:
發(fā)送方:
接收方:
執(zhí)行上面這段代碼時(shí)我們可以看到,文本中顯示frame是作為數(shù)據(jù)而不是代碼。
從上圖我們可以看到,現(xiàn)在它并不執(zhí)行代碼,而是顯示為正常的文本。