淺談IFrame式Clickjacking攻擊與防護

用IFrame內嵌其他網頁是很常見的整合技巧,兩個獨立開發網頁可分別使用,有需要再合體,被內嵌的網頁配合移除頁首頁尾只留內容,看起來天衣無縫,省事又方便。

大家猜猜以下HTML寫法會有什麼結果,網頁上有一小塊出現Google首頁?

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>IFrame Example</title>
  <style>
    iframe { width: 480px; height: 300px; }
  </style>
</head>
<body>
  <iframe src="https://www.google.com.tw" />
</body>
</html>

錯了!

用Chrome檢視上述網頁(Live Demo),IFrame一片空白:

改用IE或Edge開啟得到的訊息多一點:

Edge的錯誤訊息解釋了無法顯示Google首頁的原因:

此內容無法在框架中顯示
這裡應該要有一些內容,但發行者不允許它在框架中顯示。這是為了協助保護您可能在此網站輸入任何資訊的安全性。

解決之道是不要用IFrame內嵌,另開新視窗即可正常檢視。

透過Chrome F12工具我們可以獲得技術面的解釋,有個錯誤訊息:Refused to display 'httqs://www.google.com.tw/' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'. 檢查Response Header,的確可以看到x-frame-options: SAMEORIGIN。這是瀏覽器的安全防護特性之一,限制符合同源政策的網頁才能用IFrame、Frame或Object內嵌這個網頁。

防止網頁被內嵌目的在防止IFrame式Clickjacking攻擊(註:點擊刧持還有其他形式,本文只聚焦透過IFrame攻擊的手法),避免惡意網頁將你的網頁疊加在一般按鈕或連結上方誘使使用者點擊,不知不覺完成開放權限、身份確認… 等操作。隨便調查一下,發現不只Google,像Facebook、Twitter、Yahoo這些大網站也紛紛在HTTP Header加入X-Frame-Options: DENY或SAMEORIGIN。

由X-Frame-Options已被普遍主流網站採用的現象,若用內容農場下標風格,我們可以說:

Google、Facebook都偷偷在HTTP Header加了這個,背後的原因網站開發者們一定要知道… (謎:你夠了哦)

既然大網站都加了防護,想必此一資安風險不容忽視。但IFrame式Clickjacking真有這麼可怕,怎樣可以透過IFrame騙取使用者點擊?實際來個範例比較好懂。假設有一網頁如下,目的在偵測使用者真實身分,唯有正港豬頭才會按鈕自婊。:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <style>
        body {
            background-color: #0094ff;
        }
        button {
            background-color: red;
            color: yellow;
        }
    </style>
</head>
<body>
    <button onclick="alert('我是豬頭')">我是豬頭</button>
</body>
</html>

某駭客黑大發現此網頁未加X-Frame-Options: DENY或SAMEORIGIN防護,心懷不軌搞了個陷阱網頁:先用IFrame內嵌豬頭偵測網頁,利用CSS技巧將IFrame設成position: absolute並調整位置,將「我是豬頭」按鈕蓋在「我是帥哥」按鈕的正上方,再調整CSS opacity透明度使之完全隱形(可參考影片裡的動畫示意)。

使用者只看到「我是帥哥」,按下去一秒變豬頭:

看完示範,應該不難理解為什麼網站要加上X-Frame-Options防護。如果希望整個網站都不准其他網頁內嵌,可以設定網站伺服器在Header中預設加入X-Frame-Options。以IIS為例,可在HTTP回應標頭加入設定:

或直接修改web.config:

  <system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="X-Frame-Options" value="SAMEORIGIN" />
        </customHeaders>
    </httpProtocol>
  </system.webServer>

註:MDN網頁另有Apache、nginx設定回應標頭的方式可供參考。

不過,這個X-Frame-Options Header需要瀏覽器配合才有防護效果,萬一使用者活在世外桃源,使用的版本太舊(對,還在用IE6/IE7的無懷氏之民與葛天氏之民,我就是在說你們),這招就會破功。若要求保險,網頁可再加上:參考

<head>
  <style> body { display : none;} </style>
</head>
<body>
<script>
  if (self == top) {
    var theBody = document.getElementsByTagName('body')[0];
    theBody.style.display = "block"
  } else { 
    top.location = self.location 
  }
</script>
...
</body>

最後補充一點:針對Cross Site Scripting這類攻擊,網頁安全有個新規格-CSP(Content Security Policy),其中定義了 frame-ancestors 可取代 X-Frame-Options,但因為很多瀏覽器還不支援,現階段要防範網頁被內嵌仍是以 X-Frame-Options 為主。

【延伸閱讀】

歡迎推文分享:
Published 12 June 2016 12:38 PM 由 Jeffrey
Filed under:
Views: 17,701



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<June 2016>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication