#####前言 之前在不少p2p網站中,都有新手領取紅包的活動。這樣的紅包連接或多或少都有不少的漏洞,就是表單能夠重複提交。這樣的話,對那些p2p網站或者其餘相似的網站形成很大的損失。Fiddler你們都不陌生吧,就是一個抓包軟件。咱們先攔截url請求,Shift+R,填入壓力測試的次數,而後釋放,就會形成不少次的url訪問請求,這樣的結果很容易形成表單重複提交。那麼咱們的今天主題就是如何使用Session和Token防止表單重複提交安全
#####表單重複提交例子 在咱們寫網站的時候,確定寫過留言板的功能,可是確定對重複提交留言的惡性行爲沒有進行一些安全措施。 服務器
咱們利用Fiddler這一款抓包軟件,能夠進行壓力測試,模擬屢次url請求。就會形成如下狀況,留言板被惡性刷屏。session
#####如何進行防止表單重複提交 其實很簡單的,咱們只須要生成一個惟一的token,分別放進客戶端的表單裏和服務器的session中進行了。當咱們發起請求時,只須要判斷session中的token(如下簡稱serverToken)和客戶端表單裏的token(如下簡稱clientToken)是否相等。 若是severToken==null,clientToken==null 還有 serverToken不等於clientToken,那麼就說明表單被重複提交了。反之,若是serverToken==clientToken,就說明表單沒有被重複提交,當咱們進行了一系列須要的操做後,就能夠清除session中的token了。dom
#####具體代碼jsp
<% String token=CommonUtils.makeToken(); request.getSession().setAttribute(token,token); %>
public String uploadPhoto(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String result=null; String clientToken=request.getParameter("token"); String serverToken=(String)request.getSession().getAttribute(clientToken); if(!isRepeatCommit(serverToken, clientToken)){ result="請不要重複提交"; request.getSession().setAttribute("result",result); return "/result.jsp"; } request.getSession().removeAttribute(clientToken); }
/** * * @param serverToken * @param clientToken * @return * 若是沒有重複提交 返回true, 若是重複提交 返回fasle */ public boolean isRepeatCommit(String serverToken,String clientToken){ MyLog.i(TAG, "serverToken="+serverToken+",clientToken="+clientToken); if(serverToken==null){ return false; } if(clientToken==null){ return false; } if(!clientToken.equals(serverToken)){ return false; } return true; }
#####效果圖 我本身寫了一個圖片上傳的demo,就來測試一下是否能防止重複提交吧post
手動測試完畢了,內心確定是美滋滋了。那麼咱們用Fiddler來測試一下吧,咱們來模擬一下壓力測試。測試
#####發現的問題 寫這邊簡文的時候,我也看到其餘大牛寫的博客。在底下的評論也發現了一個存在的問題。就是打開2個上傳圖片的網頁,在第一個網頁上傳到了照片,提示"上傳成功"。而後在打開第二個網頁再上傳圖片,就會提示"請不要重複提交"。這是什麼問題形成的呢?其實仔細想一下就會發現, 當第一個網站上傳圖片成功後,就會清除Session中的token值,此時的serverToken=null了。就會形成第二個網站上傳圖片時候,serverToken=null和serverToken!=clientToken,那麼確定會提示"請不要重複提交"。網站
#####解決方案 看到這裏,大家估計還有疑問?那麼就想一下爲何我要生成惟一的Token。咱們這個Token是每一次用戶請求的標識。咱們只須要serverToken在Session中的屬性值設置爲惟一的Token便可。就不會發生剛纔的狀況。url
String token=CommonUtils.makeToken(); request.getSession().setAttribute(token,token); %>