簡訊防刷機制設計
簡訊驗證碼可以驗證手機號的有效性,簡訊驗證應用的地方越來越多,寫這篇博文的原因是因為我司最近弄了個H5活動,有個傳送簡訊驗證碼的功能由於java組沒做防刷機制導致簡訊被刷。而他們的解決辦法令我匪夷所思,因為根本起不到作用。所以想寫一篇關於防刷的博文。
簡訊被刷也算網路攻擊的一種,網路攻防一直是相愛相殺的存在。沒有絕對的防禦,只有不斷增強防禦,提高攻擊者的攻擊成本,使其攻擊成本高於收益,從而放棄攻擊。
簡訊防刷也是同樣的道理,就是不斷的增加攻擊者的攻擊成本。攻擊者一般會嘗試使用不同的攻擊方式進行試探性攻擊,根據反饋回來的資訊做進一步分析,完善攻擊方式,從而進行有效攻擊。 所以對於明顯屬於攻擊的行為,儘量不要給出明確的錯誤提示是非常重要的(業務邏輯錯誤的提示除外)。
下面給出詳細的放刷思路:
第一步,驗證請求方式
一般網頁傳送驗證碼是通過ajax傳送post請求,所以可驗證是否是ajax請求、post請求。而APP、小程式等一般傳送post請求介面,可驗證是否是post請求。如果出現這類錯誤,基本是非法攻擊行為,不要給出明確的錯誤提示,給出諸如“系統錯誤”之類的模糊提示。但,請求方式是可以偽造的,這種判斷只能過濾小白攻擊者,還需後續驗證
第二步,分析請求頭中的Referer
一般情況下,使用者先進入頁面輸入手機號然後點擊發送驗證碼,所以可以根據請求頭中的Referer來分析使用者是不是通過這個頁面地址進入的。但,Referer也是可以偽造了,但對於低階攻擊者,有可能沒想起來偽造。
前兩步可以防禦一些簡單攻擊,如果不給明確的錯誤提示,攻擊者可能要經過很多次不同的嘗試才會發現,增加了攻擊成本。
第三步,驗證手機號
一般使用正則驗證即可,這步主要是過濾無效的手機號。
第四步,驗證該手機號當天傳送了多少次驗證碼
規定每個手機號每天只能傳送多少次驗證碼,這麼做的目的是防止攻擊者利用此功能對某個手機號簡訊轟炸。雖然一般簡訊通道會對此行為做限制,但還是根據自身的需求做下防護比較好。可以利用redis等快取記憶體伺服器儲存每個手機號當天傳送的簡訊數量。
還可以根據需求,限制驗證碼的傳送頻次。
第五步,驗證該ip地址當天傳送了多少次驗證碼
規定每個ip地址每天的傳送量。不過需要注意幾點:
1、同一區域網內使用者對外訪問的ip都是同一個,值設定的過小可能會影響正常的使用者,需哦亦需要注意。
2、客戶端的ip地址不要使用請求頭中的X-FORWARDED-FOR
PHP
中$_SERVER的HTTP_CLIENT_IP
值也是不可信的,因為都可以偽造。3、由於業務特點,有可能會造成誤傷。所以最好能建立ip黑、白名單制度。通過日誌或程式碼檢測可疑的ip拉入黑名單中,對於誤傷的ip加入白名單中。
以上五步基本可以防禦絕大多數的攻擊,但對於使用代理或者攻擊者手上有大量的ip資源,還是會有被攻擊的可能。
如果還被攻擊,可以增加圖片驗證碼機制。驗證碼機制可以放在第三步和第四步之間。但是圖片驗證碼也是有可能被識別的,所以要根據攻擊強弱增加驗證碼的複雜度。
包括不限於:
1、使用複雜的規則,比如輸入計算結果、輸入指定顏色的字元中文等等。
2、多個背景圖隨機使用。
3、多種字型隨機使用。
4、字型適當傾斜、變形
5、增加長短、粗細、顏色不同的干擾線
6、增加干擾點
7、驗證成功或失敗自動切換驗證碼
。。。
這樣的話基本可以防禦99%的攻擊,如果還被攻擊,那還有最後一步:
求對面神仙放過。。。