1. 程式人生 > >Tomcat 7 新特性學習之一

Tomcat 7 新特性學習之一

Tomcat 7 Beta版本出來已經有段時間了,看了JavaEye上的朋友,還是有幾個非常勤奮每天都在學習的朋友,他們能夠每天學習,堅持下來,實屬不易,他們非常的年輕,有幾個,我還見過面,小夥子們的好學精神實在讓人敬佩。這個社會很浮躁,我自己也是這樣,尤其在杭州這種城市裡生活,會有一定的壓力,畢竟人總是想要更好的生活:想買大大的房子,買個自己喜歡的車子,自己的小孩上學不用著急她的學費。做人的樂趣很多,真想好好的去外面旅遊一番,小女兒也剛剛出生,為了去米國,早早地把她送回了老家,我很想她。期盼著公司趕緊定下來,我好回家呆上10幾天,跟女兒好好的享受一下天倫之樂。

現在上班不知道為什麼特別反感,一上班就覺得沒勁,不是因為自己沒有激情,在公司裡效率太低了,我很多的idea,都在家裡想出來的。我是會自己壓力的人,沒辦法,在這個社會生存除了興趣之外,確實還是需要像愚公移山一樣的精神,每天學習,每天進步,這樣才能不會被社會所淘汰。公司裡打工確實是不容易的事情,我們的專案早已ready,但是因為是跨國合作,想一個專案出去必須得各個方面都要準備好,這個是我一直擔心的問題,部門的發展好壞就取決於此了,真不甘心如何真的就這樣失敗了,有時候就像和平年代的軍隊一般,沒有戰可打是痛苦的,做個軍人死也要死在戰場上。我的幾個大領導是非常好的人,也是非常有經歷的人,跟他們學了很多東西。

我知道我自己的特點是什麼,我是勤奮的人,好幾個月沒有學習,實在是讓人有點心慌。想想寫blog,還是很好的方式,既然要學習和總結,那就從比較新的Tomcat 7 的新特性學起吧。

1. Use of a Nonce to Prevent Cross-Site Request Forgery (CSRF) Attacks

1) 什麼是CSRF

CSRF:Cross Site Request Forgery,跨站請求偽造,也被稱作Session Riding,它的本質是利用你的合法身份,來發送惡意請求。CSRF能夠做的事情包括:以你的名義傳送電子郵件,發訊息,盜取你的賬號,甚至購買商品,虛擬貨幣轉賬,這些東西會給你造成財產安全和個人隱私洩露等威脅。

CSRF攻擊,早在2000年已經被國外的安全人員提出,但在國內,直到2006年才開始被關注,2008年,國內外的多個大型社群和互動網站分別爆出CSRF漏洞。

2) CSRF的工作原理及示例



由上圖可以看到,攻擊者充分利用了trusted site在使用者登入以後,包含sessionID的Cookie一直儲存在客戶的PC上,當危害站點B傳送給使用者包含惡意請求的URL時,使用者點選後,不用再登陸site A,因為cookie一般儲存在http head裡,傳送給SiteA的所有請求,cookie值都會包含在之後的request裡面。如果惡意請求是刪除使用者資料,修改使用者資料等操作時,損失可能就是致命的。

典型案例如下:

I. 使用者a訪問並登入銀行網站A:http://www.asite.com

A site 以get請求可以進行轉賬服務:

http://www.asite.com/transferMoney.do?toBankAccountID=112233&amount=1000

上面URL表示,向賬號ID112233轉賬1000

II. 在使用者a仍然登入狀態時,惡意站點B給使用者a傳送電子郵件,郵件裡有url:

<a href="http://www.asite.com/transferMoney.do?toBankAccountID=112233&amount=1000">click</a>

III. 使用者a點選URL,扣款請求發生,a賬號裡面的錢就少了1000塊錢

3) Tomcat 7是如何避免CSRF的

傳統的防止CSRF攻擊的方法是使用一個隨機數(nonce),如果Wikipedia中定義的:在驗證協議中,使用一個隨機數以確保原來的通訊不能被重用。

Tomcat7定義了一個servlet過濾器,它在每一次request請求處理後,在session中儲存了一個隨機數。這個隨機數必須在隨後的請求中作為請求引數。這個Servlet filter會在伺服器端檢查請求中的隨機數是否和儲存在user session中的隨機數相同。如果相同,則這個請求只能從指定的站點而來。如果不相同,則這個請求是別的站點來的,因此會被拒絕。

這個Servlet過濾器很簡單,下面是相關的原始碼片段:

class CsrfPreventionFilter extends FilterBase {

...public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

...

String previousNonce = req.getParameter(Constants.CSRF_NONCE_REQUEST_PARAM);

String expectedNonce = (String) req.getSession(true).getAttribute(Constants.CSRF_NONCE_SESSION_ATTR_NAME);

if (expectedNonce != null && !expectedNonce.equals(previousNonce)) {    res.sendError(HttpServletResponse.SC_FORBIDDEN);

return;

}

String newNonce = generateNonce(); req.getSession(true).setAttribute(Constants.CSRF_NONCE_SESSION_ATTR_NAME, newNonce);

...

因此,每個URL必須在使用者回話中包含一個隨機數,下面是一個例子:

沒有包含隨機數的URL:

< c:url var="url" value="/show" > < c:param name="id" value="0" / >< /c:url >< a href="${show}" >Show< /a >

包含隨機數的URL:

< c:url var="url" value="/show" >

< c:param name="id" value="0" / >

< c:param name="org.apache.catalina.filters.CSRF_NONCE" value="${session.org.apache.catalina.filters.CSRF_NONCE}" / >

< /c:url >< a href="${show}">Show< /a >

參考資料

1.http://wenku.baidu.com/view/9fe72df8941ea76e58fa041b.html