原文:
http://www.cnblogs.com/jintianhu/archive/2011/08/28/2156372.html
前幾天看到浙江電信網上營業廳在搞簽到得米粒的活動,每天可簽到一次,每次獲得一個米粒,首次簽到可以獲得21個米粒。
我玩了幾天,發現了它的一個BUG。我們先看看頁面,地址是http://zj.ct10000.com/qiandao
點擊後就變灰了,當天就不能再次點了,如所示:
先來看看頁面代碼吧,用開發人員工具很容易就找到下面這個JS方法
注意紅框的代碼,它是根據前台傳過去的參數來判斷是否首次登陸。那麼如果我們每次都傳“登陸首次積分”這個字串過去呢?
測試一下,先要登陸網上營業廳,然後在簽到頁面執行如下JS代碼
?
$j.post( '/zjpr/score/qiandao/checkin.html' , { 'type' : 'WT_SIGNIN' , 'name' : encodeURI( '登入首次積分' )}, function (data){ alert(data); }); |
接著查詢一下米粒數量看看:
果然是多了21個,說明它後台沒做驗證。這時如果再次執行就沒效果了,因為後台做了同一天只能簽到一次的驗證。
那麼如果在還沒簽到的時候,同時執行多次上面的JS代碼,會怎麼樣呢?實驗一下,執行如下代碼:
?
for ( var i=0;i<10;i++){ $j.post( '/zjpr/score/qiandao/checkin.html' , { 'type' : 'WT_SIGNIN' , 'name' : encodeURI( '登入首次積分' )}, function (data){ }); } |
同時提交10個請求,看看後台是如何處理並發的。查詢一下
存在了多條記錄,米粒數從165漲到了249。說明後台沒對代碼加鎖(C#中的lock,JAVA中的synchronized),導致存在並發問題。
結論:首先還是那句話,前台驗證看需要,後台驗證不可少;其次是建議對有特殊限制的操作的相應代碼加鎖,可以對session中的對
象加鎖,這樣既限制了同一使用者的並行作業,又不影響其它使用者。
續:剛才又找到一個漏洞,可以直接無限刷米粒。原理是這樣,在簽到頁面有分享連結,可以分享到人人、開心等網站,分享一個
獲得一個米粒。但是後台沒有對分享的名稱做過濾,於是我傳了一個隨機數過去,也分享成功,獲得了一個米粒。JS代碼如下:
?
$j.post(basePath+ 'zjpr/score/qiandao/checkin.html' , { "type" : "WT_SHARE" , "channel" : Math.random(), "name" : encodeURI( "分享渠道積分" )}, function (data) { }); |
然後寫個迴圈,你們懂得。我現在已經有1500多個米粒了
我已經把BUG報給線上客服了,能不能快速處理掉就看電信的辦事效率了。