驗(yàn)證碼的幾個(gè)常見漏洞
把驗(yàn)證碼存儲(chǔ)在Cookie中
一般來(lái)說(shuō),我們會(huì)把驗(yàn)證碼的值用Session存儲(chǔ)起來(lái),通過(guò)對(duì)比用戶提交的驗(yàn)證碼和Session中的驗(yàn)證碼,就可以知道輸入是否正確。由于Session會(huì)占用服務(wù)器資源,我曾經(jīng)想過(guò)是否可以把驗(yàn)證碼的值加密后存儲(chǔ)在Cookie中。不過(guò)事實(shí)證明,這只是異想天開罷了。
假設(shè)驗(yàn)證碼的值是a,通過(guò)sha1加密后得到的值為b = sha1(a),并且把b存儲(chǔ)在Cookie中。而用戶提交的驗(yàn)證碼值為c,通過(guò)判斷sha1(c)是否與b相等,可以知道輸入的驗(yàn)證碼是否正確。然而,Cookie是受客戶端控制的。如果用戶事先通過(guò)肉眼看到驗(yàn)證碼的值是a,又從Cookie中得知此時(shí)的加密值為b,那么,他只要在提交前把Cookie的值修改為b,提交的驗(yàn)證碼值為a,就可以永遠(yuǎn)通過(guò)驗(yàn)證。
沒(méi)有進(jìn)行非空判斷
這種情況可以直接用代碼來(lái)說(shuō)明:
- if (Request["captcha"] == Session["captcha"] as string)
- {
- // 驗(yàn)證通過(guò),繼續(xù)操作
- }
假設(shè)用戶繞過(guò)了系統(tǒng)提供的表單直接提交數(shù)據(jù),此時(shí)驗(yàn)證碼還沒(méi)生成,Session["captcha"]為空。用戶不提交驗(yàn)證碼時(shí),Request["captcha"]也為空。于是,驗(yàn)證通過(guò)了。
要解決這個(gè)問(wèn)題,其實(shí)只要加個(gè)非空判斷就可以了:
- if (!String.IsNullOrEmpty(Request["captcha"]) &&
- Request["captcha"] == Session["captcha"] as string)
- {
- // 驗(yàn)證通過(guò),繼續(xù)操作
- }
沒(méi)有及時(shí)銷毀驗(yàn)證碼
使用驗(yàn)證碼要遵循一個(gè)原則,在一次比對(duì)之后,無(wú)論用戶輸入正確與否,都要立刻將驗(yàn)證碼銷毀。
如果不這樣做,就可以出現(xiàn)以下情況:
- 假設(shè)用戶輸入錯(cuò)誤,且驗(yàn)證碼沒(méi)有重新生成,那么他就可以一直嘗試,直到正確為止。雖然機(jī)器對(duì)圖片的一次性識(shí)別率比較低,但是,如果同一張圖片你給它很多次機(jī)會(huì)的話,它還是可以識(shí)別出來(lái)的。
- 假設(shè)用戶輸入成功,且驗(yàn)證碼沒(méi)有銷毀,那么在Session過(guò)期之前,他就可以一直用這個(gè)驗(yàn)證碼通過(guò)驗(yàn)證。