無所覺的表單動作, 在使用者未察覺的情形下自動送出表單
這是本人一時興起的試驗作品,寫完之後發現... 這是「惡意」的表單動作。因為我可以在使用者毫無所覺的情形下,記錄使用者瀏覽網站的每一個動作。
原始動機起於我想要在每一個連結上加上「點擊即自動加入書籤」的功能。作法是為網頁上每一個連結都加上點擊事件 (click event) 。當使用者點擊連結時,事件處理函數會自動產生一個表單 (form) ,將連結的網址及標題 (連結標籤中的文字) 填入,再自動將表單送往 黑米共享書籤 (Hemidemi) ,即完成加入書籤的動作。整個過程中,表單是不可見及不可察覺的。瀏覽器仍然會載入連結,而使用者不會察覺到表單送出動作。
範例網頁 normal.html
這是一個非常平凡的網頁,裡面有三個連結。我說過要用點擊事件觸發自動表單動作,但這裡看不到任何傳統的 onclick=xxx 敘述。實則玄機都在第 15 行載入的 watch.js 中。
watch.js
在 watch.js 中,為 window.onload 事件指派了一個事件處理函數。該函數抓出了網頁中的所有連結,然後為這些連結指派了 onclick 事件處理函數 gotYou() 。這是第一步:為每個連結添加點擊事件處理函數。
看到 gotYou() 的內容,由於表單呈送動作 (submit) 一定會觸發瀏覽器載入新頁面的動作,為了讓使用者無所覺,必須建立一個 iframe 並將其指派為表單的動作目標視窗 (target) 。gotYou() 接著自動建立一個表單及表單欄位,並填入欄位內容。最後送出表單 (form.submit();) 。iframe 和表單都設定不顯示,因此使用者不會察覺我已經產生一個表單並將其送出。
看到此處,有興趣的讀者可以將範例網頁和 watch.js 存起來,將 watch.js 第 32 行的 action 指派之內容改成黑米書籤的書籤建立服務 (即第 31 行的網址) 。啟動瀏覽器,先登入黑米書籤再開啟範例網頁,接著點擊任一連結。瀏覽器照常載入連結的網頁,看似一切正常。這時請再回到黑米書籤,將會發現剛才的網頁已經被加入共享書籤了。
在 IE 中 (我測的是 IE6) ,此處無法指派表單動作目標為 iframe ,送出表單時 IE 會自動開啟新視窗載入表單的回傳結果。所以用 IE6 時,會看到瀏覽器新增了一個視窗,而新視窗中會顯示黑米書籤中加入了一個新書籤。
i_know_where_you_go.php
如果我只做到上面為止,或許看起來是個「體貼的自動化功能」。但接下來我要寫一個簡單的 PHP 程式 (i_know_where_you_go.php) 放在網路上,並將 watch.js 中的表單動作網址指派為這個 PHP 程式。同樣的動作,現在變成了一個使用者動作的記錄器。使用者在這頁面上點了什麼連結,全都記錄在 i_know_where_you_go.log 之中。
剛剛 IE 的使用者還會看到新視窗,這裡我加上了 window.close() 敘述直接把新視窗關掉。現在 IE 的使用者點擊連結後,只會發現「好像」閃了一下,接著注意力就放在載入的連結網頁上。渾然不知剛剛的點擊動作已經被我記錄下來了。
具有資安意識的讀者,應該已經想到如果自己的網頁被人植入一行–僅僅一行– JavaScript 的載入標籤,就足以把所有瀏覽自己網頁的參觀者都出賣了。
Posted by shirock at
樂多Roodo! │22:56
│
回應(8)
│
引用(1)
│
JavaScript
引用URL
http://cgi.blog.roodo.com/trackback/2665954
JavaScript Hijacking: 如何透過瀏覽器取得基於 Ajax 及 JSON 規範傳遞之跨網域的隱密資料。
gotYou function這樣寫好像比較好寫一點?
可參考此篇
http://qtutu.com/blog/?p=11
function gotYou(a){
var dummyImage = new Image();
dummyImage.src = "http://www.hemidemi.com/user_bookmark/create?user_bookmark[url]=" + a.href + '&user_bookmark[title]=' + a.childNodes[0].nodeValue;
}
這兩種寫法有所差異。
image.src 的寫法,送出的是一個 HTTP GET request 。
我的寫法則是送出 HTTP POST request ,See 第29行。
黑米書籤沒有區分表單資料來源,是以用 GET request 也可以達成同樣目的。若表單目標區分表單資料來源,例如是一個 PHP 程式,而且只認 $_POST 的內容,則經由 GET request 送來的表單資料不會被處理。
還有一件事,經由 image.src 送出的內容,沒有各瀏覽器一致通用的方法可以分析回應內容 (like XmlHttpRequest.reponseText)。透過 form 的提交動作,則會獲得一個新頁面內容,可以再做其他事。例如上例會關閉新開啟的視窗。

0.0 如果他是用新版IE 開分頁 那window. close執行後 他會詢問要不要關閉

ie6之所以無法設定target到動態產生的iframe
原因是因為動態產生的iframe她沒把iframe物件參照記錄進window.frames陣列中
所以只要手動替IE寫進去就可以同樣使用target去指定post目標頁框

不好意思 更正一下
應該不能說沒寫進frames中
而是IE沒用frame name當陣列索引
你們說的事,應該都是現在的 IE7, IE8 修正過後的結果了。
畢竟這是一篇兩年前貼的舊文。也正如我所說的,這可以變成一個惡意的網頁動作。所以這一、兩年來,瀏覽器也漸漸修正了這些不適當的動作。

恩恩..
老實說在我工作環境沒有像前輩這樣的程式設計師
都是一些老派IE6 ONLY的設計師
改天有機會在向您請教一番
我先把您網站上的文爬一爬
也許我是更老派的設計師。
因為我從 Netscape 2, IE 3 就在上面寫 JavaScript跟 DnyamicHTML 了。
更古怪的瀏覽器行為我都碰過啊 XD