JavaScript Hijacking and How to
日前 Fortify 發表了一份文件《Fortify Software Documents Pervasive and Critical Vulnerability in Web 2.0》,描述惡意網站如何透過瀏覽器取得基於 Ajax 及 JSON 規範傳遞之跨網域的隱密資料。它將此方式稱之為 JavaScript Hijacking 。詳細的 Hijacking 內容請至《JavaScript Hijacking Vulnerability Detected》下載文件。
本文將說明 JavaScript Hijacking 概念以及一個範例。
JavaScript Hijacking 的運作概念
近來許多網站皆引入 Web 2.0 的概念,大量使用 Ajax 與 JSON 技術,透過非同步載入資料的方式,提供許多互動功能。這些載入資料就是 JavaScript Hijacking 的目標。
JavaScript Hijacking 並不需要入侵目標網站植入任何程式碼,只需要使用者正常地登入目標網站,再等待他們瀏覽包含 JavaScript Hijacking 程式碼的惡意網頁即可。這並不困難,因為很多使用者皆有登入一大堆網站後,再四處瀏覽各種網頁的習慣。例如你是一個 Gmail 用戶,那麼你打開瀏覽器後的第一件事,大概就是先登入 Gmail 網頁,接著你會開啟其他瀏覽器視窗繼續觀看其他網頁。若是其中有一個惡意網頁鎖定 Gmail 用戶進行 JavaScript Hijacking 攻擊,當你一瀏覽這個惡意網頁,它就可以透過 JavaScript –如同 Gmail 網頁所採用的方式– 向 Gmail 伺服器索取你的資料。
How to Hijacking
在 Ajax 技術中,我們通常使用 XmlHttpRequest
傳輸資料,而它在使用上有個安全性限制,即禁止跨網站的資料傳送。基本上,這項限制非常管用。然而熟悉 Ajax 技術的程序員知道還有其他手段可以非同步地傳輸資料,例如《Load and Execute JavaScript on Demand, by createElement》就是採用 <script>
標籤載入資料。這也正是 JavaScript Hijacking 所採用的方式。接下來我將示範如何 Hijacking 。
首先,我先設計一個簡單的網頁當作使用者每天都會固定登入瀏覽的網站。當使用者尚未登入前,會傳回一份要求使用者登入的 HTML 文件。當使用者輸入 xyz 登入後,則傳回一份含有使用者資訊的 JSON 文件。網址設定為 http://localhost/test/session_hijacking.php。源碼如下列所示:
接著,我另外設計一個包含 JavaScript Hijacking 程式碼的惡意網頁,名為 hijacking.html ,源碼如下列所示:
Hijacking 的重點在前後兩段,首先覆寫 JavaScript 內建 Object
類別的建構子內容,即第6-8行之程式碼(此程式碼僅在Firefox有效,IE的JScript則用其他方式覆寫建構子)。由於 Object
是 JavaScript 之最上層基礎類別,如此一來當 JavaScript 建構任何個體時,都會執行第6-8行的內容。在此只是簡單地令 hijackingData 指涉最近一個建構的個體。最後,以 <script>
非同步地載入 http://localhost/test/session_hijacking.php 的資料。
操作圖例
我們先開啟一個瀏覽器視窗瀏覽 http://localhost/test/session_hijacking.php ,先不要登入。再開啟另一個瀏覽器視窗瀏覽 hijacking.html。
然後,我們在正常網頁的表單中輸入 'xyz' 登入。現在我們看到正常網頁回傳了一份使用者資訊的 JSON 文件。接著,我們只要在惡意網頁的瀏覽器視窗按一下重新整理,惡意網頁就會跳出訊息視窗,顯示它已經逮到使用者理應僅在正常網站之下可以看到的資料。
防治方式
Fortify 在《JavaScript Hijacking Vulnerability Detected》之文件中已提出防治方式,在此僅簡述之。
- 僅允許使用 HTTP POST method 傳輸資料
- 因為
<script>
使用 HTTP GET method 取得資料,改用 HTTP POST method 可減少 hijacking 機會。然而《在使用者未察覺的情形下自動送出表單》一文中證明,我們還是有辦法發動 HTTP POST method 。 - 檢查
referer
- 伺服端須檢查使用者瀏覽網頁之
referer
是否來自相同網域。 - 加上注釋符號或是改用 XML 格式
- 在《Load and Execute JavaScript on Demand, by createElement》中提到,以
<script>
載入資料時,便立即執行,不能選擇執行時機,也不能僅執行片段內容。因此外部文件必須是一個純 JavaScript 文件
。若在 JSON 資料前後加上注釋符號,如/*[{"title": "xyz"}]*/
,便可令 JavaScript 視之為一般注釋而不加以執行,如此便不會喚起 Hijacking 程式碼。當然,改用 XML 格式也有同樣效果。再參閱《JSON 的安全性》了解載入 JSON 的安全作法。
Fortify 還檢測了12種常見的 Ajax framework ,有 DWR, GWT, Atlas, Dojo, jQuery, MochiKit, Moo.fx, Prototype, Rico, Script.aculo.us, xajax, Yahoo UI 。目前僅 DWR 2.0 建置了防治措施,其他沒有。
祝各位程序員清明連假,假期愉快。
樂多舊回應