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

對于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,處理不同的場景和需求。今天介紹的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的實現。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容