資安JAVA(六):跨站請求偽造(CSRF)

來源:John Melton's Weblog
標題:YEAR OF SECURITY FOR JAVA – WEEK 6 – CSRF PREVENTION IN JAVA
作者:John Melton
內容:
What is it and why should I care?

跨站請求偽造攻擊(CSRF),是一種受害者在不知不覺中,以自己合法的身分向某個網站執行一段指令。原本,合法"身分證明"通常存存放在客戶端的cookie,而使用者每一次向網站要求服務都需附上身份證明。若存在漏洞,攻擊者可以假借受害者的身分向某個沒有抵抗CSRF的網站,執行幾乎所有要求。

以下是CSRF的運作圖:

第一步:受害者被導引到惡意網站。
第二步:受害者開始下載惡意的網站內容,其中一張圖片的src指向目標網站good.com。
第三步:受害者的瀏覽器讀取惡意圖片的src,並且以合法的session在目標網站,執行交易要求。
第四步:交易完成,受害者全然不知。

What should I do about it?

讓我們想一想跨站請求偽造如何攻擊,其危險之處? 再來想解決方案。

Token 標記
利用同步Token設計模式是最經典的解法。以下是基本步驟:
第一步,使用者登入後,server端產生亂數標記,並儲存到使用者session。
第二步,所有 不允許重複送出相同資料 的Web表單,都需要加入使用者的Token。
第三步,Server端處理表單要求時,須驗證送來的Token和使用者session中的Token相同,只有有異就終止交易。

這些年這個方法多年來適用於大部分情況。但有兩個缺點,一是實作很花時間,二是特殊情況下有機會偽造驗證結果。

OWASP組織的 ESAPI 專案也能避免CSRF,除了實作時要額外考慮身分授權的架構。點擊 這裡 ,有一個作者製作說明 ─ 如何利用ESAPI抵擋CSRF。

CSRFGuard
OWASP 的CSRFGuard 專案是一個非常好的防禦函式庫。重點在於只要較少的工作量,增加一個filter去處理表單要求和更新一個網站設定檔。非常值得研究一下。
Stateless CSRF Protection
還有一個有趣的方法,無狀態CSRF保護(此方法作者是John Wilander)。萬一你不想要安置任何Token在Session中,可以考慮 John 提出的似乎很棒的方法。方法是允許客戶端產生Token,並存放在Cookie中,每當使用者按下送出Submit都要加入此Token到Request中的參數。


只要攻擊者無法同時擁有伺服端送給客戶端的Cookie和 客戶端送給伺服端Request的參數,伺服器只要確保Cookie的值和Request的值相同,應該就可以避免CSRF

然而,目前尚未證明這樣的效果,這是相當有代表性和聰明的方法,因為 John Wilander 用簡單的方法解決困難的問題。或許經過時間的考驗後,我們會知道這個前瞻性的解決方案成效如何。

CSRF是廣泛的且危險的攻擊,只要參考以上方法就能妥善應付。

最後一點,使用Token的方法在有XSS弱點的網站中是無效的。因為攻擊者可以XSS你的網站,就可以讀取網站內容而且解析出Token,使得 Token 失效。所以記得先解決XSS的臭蟲吧 !

(更多CSRF資料可參考 OWASP wiki。)
———–———–
資安Java: 上一篇 || 下一篇
———–———–

留言

這個網誌中的熱門文章

資安JAVA(十):X-Content-Type-Options

資安JAVA(十一):X-XSS-Protection

資安JAVA(四):Session Cookie HTTPOnly Flag