W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
“點(diǎn)擊劫持”攻擊允許惡意頁(yè)面 以用戶的名義 點(diǎn)擊“受害網(wǎng)站”。
許多網(wǎng)站都被黑客以這種方式攻擊過(guò),包括 Twitter、Facebook 和 Paypal 等許多網(wǎng)站。當(dāng)然,它們都已經(jīng)被修復(fù)了。
原理十分簡(jiǎn)單。
我們以 Facebook 為例,解釋點(diǎn)擊劫持是如何完成的:
<iframe>
?,其 ?src
? 來(lái)自于 facebook.com,這使得“點(diǎn)贊”按鈕恰好位于該鏈接上面。這通常是通過(guò) ?z-index
? 實(shí)現(xiàn)的。這是惡意頁(yè)面看起來(lái)的樣子。為了清楚起見(jiàn),我們將 <iframe>
設(shè)置成了半透明的(在真正的惡意頁(yè)面中,它是全透明的):
<style>
iframe { /* 來(lái)自受害網(wǎng)站的 iframe */
width: 400px;
height: 100px;
position: absolute;
top:0; left:-20px;
opacity: 0.5; /* 在實(shí)際中為 opacity:0 */
z-index: 1;
}
</style>
<div>點(diǎn)擊即可變得富有:</div>
<!-- 來(lái)自受害網(wǎng)站的 url -->
<iframe src="/clickjacking/facebook.html"></iframe>
<button>點(diǎn)這里!</button>
<div>……你很酷(我實(shí)際上是一名帥氣的黑客)!</div>
在上面這個(gè)示例中,我們有一個(gè)半透明的 <iframe src="facebook.html">
,我們可以看到,它位于按鈕之上。點(diǎn)擊按鈕實(shí)際上會(huì)點(diǎn)擊在 iframe 上,但這對(duì)用戶不可見(jiàn),因?yàn)?iframe 是透明的。
結(jié)果,如果訪問(wèn)者登陸了 Facebook(“記住我”通常是打開的),那么這個(gè)行為就會(huì)點(diǎn)一個(gè)“贊”。Twitter 上是 “Follow” 按鈕。
下面是相同的示例,但 iframe
的透明度設(shè)置為了 opacity:0
,更符合實(shí)際情況:
我們進(jìn)行攻擊所需要做的 —— 就是將 <iframe>
放置在惡意頁(yè)面中,使得按鈕恰好位于鏈接的正上方。這樣當(dāng)用戶點(diǎn)擊鏈接時(shí),他們實(shí)際上點(diǎn)擊的是按鈕。這通??梢酝ㄟ^(guò) CSS 實(shí)現(xiàn)。
點(diǎn)擊劫持是對(duì)點(diǎn)擊事件,而非鍵盤事件
此攻擊僅影響鼠標(biāo)行為(或者類似的行為,例如在手機(jī)上的點(diǎn)擊)。
鍵盤輸入很難重定向。從技術(shù)上講,我們可以用 iframe 的文本區(qū)域覆蓋原有的文本區(qū)域?qū)崿F(xiàn)攻擊。因此,當(dāng)訪問(wèn)者試圖聚焦頁(yè)面中的輸入時(shí),實(shí)際上聚焦的是 iframe 中的輸入。
但是這里有個(gè)問(wèn)題。訪問(wèn)者鍵入的所有內(nèi)容都會(huì)被隱藏,因?yàn)樵?iframe 是不可見(jiàn)的。
當(dāng)用戶無(wú)法在屏幕上看到自己輸入的字符時(shí),通常會(huì)停止打字。
最古老的防御措施是一段用于禁止在 frame 中打開頁(yè)面的 JavaScript 代碼(所謂的 “framebusting”)。
它看起來(lái)像這樣:
if (top != window) {
top.location = window.location;
}
意思是說(shuō):如果 window 發(fā)現(xiàn)它不在頂部,那么它將自動(dòng)使其自身位于頂部。
這個(gè)方法并不可靠,因?yàn)橛性S多方式可以繞過(guò)這個(gè)限制。下面我們就介紹幾個(gè)。
我們可以阻止因更改 beforeunload 事件處理程序中的 top.location
而引起的過(guò)渡(transition)。
頂級(jí)頁(yè)面(從屬于黑客)在 beforeunload
上設(shè)置了一個(gè)用于阻止的處理程序,像這樣:
window.onbeforeunload = function() {
return false;
};
當(dāng) iframe
試圖更改 top.location
時(shí),訪問(wèn)者會(huì)收到一條消息,詢問(wèn)他們是否要離開頁(yè)面。
在大多數(shù)情況下,訪問(wèn)者會(huì)做出否定的回答,因?yàn)樗麄儾⒉恢肋€有這么一個(gè) iframe,他們所看到的只有頂級(jí)頁(yè)面,他們沒(méi)有理由離開。所以 top.location
不會(huì)變化!
sandbox
特性的限制之一就是導(dǎo)航。沙箱化的 iframe 不能更改 top.location
。
但我們可以添加具有 sandbox="allow-scripts allow-forms"
的 iframe。從而放開限制,允許腳本和表單。但我們沒(méi)添加 allow-top-navigation
,因此更改 top.location
是被禁止的。
代碼如下:
<iframe sandbox="allow-scripts allow-forms" src="facebook.html"></iframe>
還有其他方式可以繞過(guò)這個(gè)弱雞防御。
服務(wù)器端 header X-Frame-Options
可以允許或禁止在 frame 中顯示頁(yè)面。
它必須被完全作為 HTTP-header 發(fā)送:如果瀏覽器在 HTML <meta>
標(biāo)簽中找到它,則會(huì)忽略它。因此,<meta http-equiv="X-Frame-Options"...>
沒(méi)有任何作用。
這個(gè) header 可能包含 3 個(gè)值:
?DENY
?
始終禁止在 frame 中顯示此頁(yè)面。
?SAMEORIGIN
?
允許在和父文檔同源的 frame 中顯示此頁(yè)面。
?ALLOW-FROM domain
?
允許在來(lái)自給定域的父文檔的 frame 中顯示此頁(yè)面。
例如,Twitter 使用的是 X-Frame-Options: SAMEORIGIN
。
結(jié)果如下:
<iframe src="https://twitter.com" rel="external nofollow" ></iframe>
上面這個(gè) iframe
可能為空,或者通過(guò) alert 告知你瀏覽器不允許以這種方式導(dǎo)航至該頁(yè)面,這取決于你的瀏覽器。
X-Frame-Options
有一個(gè)副作用。其他的網(wǎng)站即使有充分的理由也無(wú)法在 frame 中顯示我們的頁(yè)面。
因此,還有其他解決方案……例如,我們可以用一個(gè)樣式為 height: 100%; width: 100%;
的 <div>
“覆蓋”頁(yè)面,這樣它就能攔截所有點(diǎn)擊。如果 window == top
或者我們確定不需要保護(hù)時(shí),再將該 <div>
移除。
像這樣:
<style>
#protector {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 99999999;
}
</style>
<div id="protector">
<a href="/" target="_blank">前往網(wǎng)站</a>
</div>
<script>
// 如果頂級(jí)窗口來(lái)自其他源,這里則會(huì)出現(xiàn)一個(gè) error
// 但是在本例中沒(méi)有問(wèn)題
if (top.document.domain == document.domain) {
protector.remove();
}
</script>
samesite
cookie 特性也可以阻止點(diǎn)擊劫持攻擊。
具有 samesite
特性的 cookie 僅在網(wǎng)站是通過(guò)直接方式打開(而不是通過(guò) frame 或其他方式)的情況下才發(fā)送到網(wǎng)站。更多細(xì)節(jié)請(qǐng)見(jiàn) Cookie,document.cookie。
如果網(wǎng)站,例如 Facebook,在其身份驗(yàn)證 cookie 中具有 samesite
特性,像這樣:
Set-Cookie: authorization=secret; samesite
……那么,當(dāng)在另一個(gè)網(wǎng)站中的 iframe 中打開 Facebook 時(shí),此類 cookie 將不會(huì)被發(fā)送。因此,攻擊將失敗。
當(dāng)不使用 cookie 時(shí),samesite
cookie 特性將不會(huì)有任何影響。這可以使其他網(wǎng)站能夠輕松地在 iframe 中顯示我們公開的、未進(jìn)行身份驗(yàn)證的頁(yè)面。
然而,這也可能會(huì)使得劫持攻擊在少數(shù)情況下起作用。例如,通過(guò)檢查 IP 地址來(lái)防止重復(fù)投票的匿名投票網(wǎng)站仍然會(huì)受到點(diǎn)擊劫持的攻擊,因?yàn)樗皇褂?cookie 對(duì)用戶身份進(jìn)行驗(yàn)證。
點(diǎn)擊劫持是一種“誘騙”用戶在不知情的情況下點(diǎn)擊惡意網(wǎng)站的方式。如果是重要的點(diǎn)擊操作,這是非常危險(xiǎn)的。
黑客可以通過(guò)信息發(fā)布指向他的惡意頁(yè)面的鏈接,或者通過(guò)某些手段引誘訪問(wèn)者訪問(wèn)他的頁(yè)面。當(dāng)然還有很多其他變體。
一方面 —— 這種攻擊方式是“淺層”的:黑客所做的只是攔截一次點(diǎn)擊。但另一方面,如果黑客知道在點(diǎn)擊之后將出現(xiàn)另一個(gè)控件,則他們可能還會(huì)使用狡猾的消息來(lái)迫使用戶也點(diǎn)擊它們。
這種攻擊相當(dāng)危險(xiǎn),因?yàn)樵谠O(shè)計(jì)交互界面時(shí),我們通常不會(huì)考慮到可能會(huì)有黑客代表用戶點(diǎn)擊界面。所以,在許多意想不到的地方可能發(fā)現(xiàn)攻擊漏洞。
X-Frame-Options: SAMEORIGIN
?。<div>
? 對(duì)整個(gè)頁(yè)面進(jìn)行遮蓋,這樣也是安全的。Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: