閒閒沒事在Google搜尋我自己部落相關的關鍵字,想看看能見度多高還有會顯示什麼東西,我搜尋表單攻擊,卻看到別人部落上寫了一篇表單安全性的文章,突然有感而發,我也來發表這類的東西。
--只是個人淺見,若有高手歡迎指正。--
首先撰寫表單堅持一些要點就不容易被攻擊。
一、過濾所有Request變數。
最基本的防禦XSS,那些JavaScript寫成的惡意程式碼,還有跨站框架……等等攻擊。最主要只要擋掉「HTML」標籤就可以了,問題是,萬一我要開放HTML給使用者使用,這下才是真的麻煩,如果真如此就只好開放BBcode囉。千萬不要直接允許用戶輸入HTML,即使是限制也是有問題的。
攻擊者可以利用事件 onClick、onError、onLoad 之類的方式觸發XSS攻擊。危險。
Replace掉所有「<」、「>」、單雙引號,就安全了嗎?Maybe,Maybe Not。
有些人就直接 Replace 掉 <script ,感覺上很對,實際上有很大的漏洞。
如果我寫 「<script<scr<scriptipt>」被過濾掉一次之後會變為「<script>」,像這種清除字串,最好寫一個 while true ,刪乾淨,搜尋到就刪,直到沒搜尋到為止。(萬不得已才這樣做)
個人建議全部改用 HTML 編碼,全面HTML編碼(HTML編碼就是 &#Unicode; 的形式的字串),若有引數是在資料庫語句的話就請不要用 XXX=XXX 的形式(數字型態),全部改用 XXX="XXX" 之類的,一定要有引號框住。並且過濾掉所有單雙引號<>以及反斜線。
至於傳進變數的方式,建議通通改成 POST ,不要使用 GET ,除非分頁設計還是什麼的,不然絕對沒必要使用 GET ,很危險。這有牽扯到某些伺服器的有啟用magic quotes,會自動脫逸引號字元,所以用POST會較為安全一些。而且POST,攻擊者比較不好攻擊。
還有COOKIE、Header 傳進來的 也建議 過濾掉。
二、不使用cookie、鎖定session以及IP。
又要再次重申 cookie 的危險程度,我幾乎寫程式只用 session 完全不使用 cookie,我知道session 有所謂的 SESSION_id 是透過 cookie 所存,所以攻擊者只要獲取其他人的 session ID,即可使用 cookie 欺騙 就這樣簡單的取得他人的帳號權限。
網路上有一堆防禦方法是 透過IP UserAgent 算出來的 MD5 作為安全碼,只要進來的安全碼和之前不同就登出用戶,是一個很棒的方式,不過很麻煩。這對登入表單有一些效果,如果是留言表單,我故意關閉cookie,讓server的session id 跳錯,這樣就很有可能可以直接不經過驗證碼就可以留言(前提是對方沒有檢查session驗證碼的值是否為空)。
我的作法是強制鎖定 session ID 為 IP 的 md5 值,這樣也許會有點不方便,不過我覺得這樣反而好一點,不需要擔心什麼 session 挾持,或是 對方換一個新的 ID 進來,明明被 ban 15分鐘又可以繼續留言。
三、防止表單偽造、防止惡意灌水
什麼是表單偽造,表單傳入的值可以直接當成 name=value&name2=value2 ... 無限延伸,檢查也是檢查值,很多後端程式 根本不管從哪來 Request 進來的,這給攻擊者很大的方便,只要複製一分一模一樣的表單,就可以無限偽造一堆請求過去。
有些會透過 Header 的 Referer 來檢查 轉介站,不過 Header 也是可以偽造的。
所以,最好是在 表單一訪問的情況 就立刻生成一個 Key ,當值傳到後端處理的時候,就檢查那個 Key 有沒有相同,不同就是表單偽造,然後每次通過驗證就銷毀 Key重新生成一個新的,而攻擊者為了取得Key,必須一直不斷的向 「原始」 表單請求 ,獲取裡面的 Key 才可以發送資料。
這原理跟驗證碼有點相似,現在很多網站都有圖形驗證碼了。不過一樣也有一些是沒有驗證碼的,驗證碼是一定要有的!不然會被惡意攻擊,
而那些使用 「文字」驗證碼的人,自以為很安全,其實很危險。我近期開發出來的表單攻擊程式就可以破解文字驗證碼!即使是要經過數學運算的也是一樣可以破解。
意味著我可以提交完就訪問原始網站,分析驗證碼,又提交,又訪問原始網站,分析驗證碼,又提交……
唯有圖形驗證碼才可以防禦此類攻擊。文字驗證碼根本不可靠。