Tomcat 怎樣防止跨站請求偽造(CSRF)

MittieAnnoi 8年前發布 | 51K 次閱讀 CSRF Tomcat 應用服務器

對于CSRF,可能一些朋友比較陌生。我們下面先簡單介紹下。

什么是CSRF呢,我們看下Wikipedia的說明:

Cross-site request forgery,即跨站請求偽造,也稱為 "One Click Attach" 或者"Session Riding",常縮寫成CSRF。是 通過偽裝來自受信任用戶的請求來利用受信任的網站

其中,說起CSRF,經常會舉的一個例子,是這樣的:

用戶A在訪問網上銀行,在銀行網站里進行了一些操作后。

之后點擊了一個陌生的鏈接。而這個鏈接,是用戶B提供的一個惡意網頁W,網頁W內也包含訪問和用戶A相同銀行信息的鏈接,可能是轉帳,也可能是修改密碼。

此時如果A的認證信息還未過期,就會被直接利用,成功幫助W進行了銀行網站的對應操作,而這一切,都是在A不知情的情況下進行的。

為了防范CSRF,常見的方式有:

  • 請求中包含隨機token信息

  • Cookie中包含csrf token信息

  • 其他的驗證請求頭Refer等...

在Tomcat中,默認提供了一個防范CSRF的好工具: CSRF Prevention Filter

Tomcat默認提供了各類的Filter,處理不同的場景和需求。像我們前面介紹過的處理編碼的 Tomcat自帶的設置編碼Filter , 還有進行跨域處理的 Tomcat與跨域問題 等等。今天介紹的CSRF Prevention Filter也是其中的一個。

整個Filter的工作流程可以概括成以下內容:

該Filter為Web應用提供了基本的CSRF 保護。它的filter mapping對應到 /*

并且所有返回到頁面上的鏈接,都通過調用 HttpServletResponse # encodeRedirectURL(String) 或者 HttpServletResponse # encodeURL(String) 進行編碼。實現機制是生成一個token并且將其保存到session中,URL的encode也使用同樣的token,當請求到達時,會比較請求中的token和session中的token是否一致,只有相同的才允許繼續執行。

我們通過一個例子,深入源碼,來了解下內部的實現細節。

還是使用Tomcat自帶的Manager應用來看下。

在其 web.xml 中,有這樣的配置:

下面的內容是CsrfPreventionFilter的 doFilter 方法,

我們注意到前面的配置里包含一個entryPoints,對照代碼,馬上就能明白,這項配置用來做類似于exclude的功能,在配置中的映射,可以跳過檢查。

而如果沒有在entryPoints中,同時在session存在,但不包含對應的Nonce,就會直接返回 403 (SC_FORBIDDEN)。

如果session不存在,就會在doFilter中走到下面的內容:

做為初次請求,會在session中保存對應的Attribute,同時添加到一個LruCache中。這里的重點在于,使用了HttpServletResponseWrapper的子類 CsrfResponseWrapper 替換了它做為response傳入后續的流程 。

所以,后面所有調用encodeUrl的地方,其實實際調用到的是這個:

public String encodeURL(String url) {

return addNonce (super.encodeURL(url));

}

addNonce對應的,是在傳入URL后面增加csrf token或者是nonce的標識,用于后續請求時的識別。

頁面具體的編碼操作,則是對response的encodeURL的使用,也就是我們上面addNonce的使用:

對應到Manager應用,它的頁面是通過Servlet輸出的,所以具體的邏輯在Java文件中,我們在頁面上的連接觀察到,此時獲取應用列表的請求URL變成了這樣:

http://localhost:8080/manager/html/list? org.apache.catalina.filters.CSRF_NONCE =6BC061DD606D7BA1BDEF7F40657F0C47

每個不在entryPoints中的請求,都會加上org.apache.catalina.filters.CSRF_NONCE=6BC061DD606D7BA1BDEF7F40657F0C47

這種形式的URL輸出,就是在頁面上調用encodeURL的結果,對應的Manager中的代碼是這個樣子:

以上,就是CSRF Prevetion Filter實現的原理和細節。當然,上面返回403的地方,以及生成nonce的地方,都可以通過Filter提供的參數來進行配置,分別對應到denyStatus和randomClass。后者需要提供一個Random的實現。

 

 

來自:http://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650859236&idx=1&sn=426730453a1a0496594cc6808e497a8f&chksm=f1329937c64510212fa8034f7954583871b2fc8c32a71d0f068f2bccb0d0170e6cd22998ed7f

 

 本文由用戶 MittieAnnoi 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!