前面從 Day8 到 Day19 都是在講要怎麼模仿 Github,今天則是要反過來,談談身為一個網站的開發者,該注意哪些事項才能避免網站被 reverse proxy 模仿
可以在前端加一段檢查網址的程式碼,譬如說檢查 host
跟 origin
,如果是發現是假冒的網站就 alert
跳出警告視窗
const host = location.host, origin = location.origin
if(host !== 'github.com' || origin !== 'https://github.com'){
alert('這個是釣魚網站')
}
但我們在 Day10-替換頁面中的網址 中有提到其實 reverse proxy 可以在轉發的過程中修改 html/js 裡面的內容,所以你的程式碼就有可能被改成下面這樣,就不會跳出警告視窗
if(host !== 'phish-github.com' || origin !== 'https://phish-github.com'){
alert('這個是釣魚網站')
}
為了不被取代你可能要把 github.com
拆成兩個變數,這樣就不會直接被 replace('github.com', 'phish-github.com')
取代掉
if(host !== 'github' + '.com'){
alert('這個是釣魚網站')
}
但如果有心人真的要模仿你的網站的話光靠這招是擋不住的,只能拖延一些時間,畢竟他可以隨意竄改你的前端程式碼,只要花點時間 trace code 還是可以找出埋藏在其中的關鍵
domain
、secure
屬性在 Day11-登入 I(原理篇) 中有講到 cookie 的原理跟屬性,為了安全一定要設 domain
跟 secure
,雖然我們在 Day13 馬上就破解了XD,但不見得每個釣魚網站開發者都能發現是 cookie 在搞鬼,所以還是可以提昇安全性,也增加一些破解需要花的時間
Host-
、Secure-
開頭如果行有餘力的話還可以把一些關鍵 cookie 改成 __Host-
或是 __Secure-
開頭,就像在 Day18-發 issue I(觀察篇)
中提到的:這樣可以強制該 cookie 一定要有 secure
屬性,但這也代表你在 local 開發時也需要用 HTTPS,會有點麻煩,所以真的行有餘力再做就好了
在前端向後端發請求時帶上一些驗證用的 header,譬如說加上一個 X-Domain
表示目前的網域,如果後端判斷網域錯了就直接回絕請求
ajax({
method: 'GET'
url: '/api/user/email',
header: {
'X-Domain': location.host
}
})
或是加在 POST
請求的 body 也是不錯的方法,如果 domain
不對就直接不給登入,然後趕快寄信通知使用者改密碼
ajax({
method: 'POST'
url: '/api/login',
body: {
user: form.user,
password: form.password,
domain: location.host
}
})
但這個方法跟第一個 在前端檢查網址 一樣,如果有心人真的要模仿你的網站,他可以在轉發的過程中直接竄改你的扣,讓你的驗證機制失效,所以可以防一些普通人但防不了很會 trace code 的高手
網路上有許多像是 Get My IP 的服務可以讓你查到你的 IP 位址是多少,通常每個人的 IP 會不太一樣
但假如有很多使用者在用我們做的 Phish Github,因為所有請求都是透過 reverse proxy 轉發給 Github,所以 Github 會看到有大量請求來自 Phish Github 的 IP,然後就可以發現這個 IP 是釣魚網站,前提是 Github 有把所有請求的 IP 來源記錄起來而且分析
但這也只能算是事後補救,沒辦法在事發的第一時間就防住
今天講的是如何防範,但講了這麼多還是沒有提出一個保證有用的方法XD,畢竟道高一尺魔高一丈,所有的流量都會經過 reverse proxy,在轉發的過程中又可以任意竄改 header、cookie、js 等等各式各樣的資料,所以根本不可能完全擋住,只能不斷提高難度跟複雜度,等有一天已經複雜到沒有人想花心思破解時,你的網站就真的安全了XD
至於要把驗證機制做到那麼複雜需要付出多少開發、維護成本?不要問我 我也不知道