短信API接口在web中獲得愈來愈多的應用,如用戶註冊,登陸,密碼重置等業務模塊都會使用手機驗證碼進行身份驗證。通常狀況下,咱們會採用這樣的安全策略,將短信發送頻率限制在正常的業務流控範圍內,好比,一個手機號一天最多下發10條短信,同時限制時效,驗證次數。但這樣的策略,攻擊者經過遍歷手機號,仍是阻止不了短信資源被消耗的狀況。前端
如何防止短信api接口遍歷呢?web
在平時瀏覽網站的時候,我會稍微留意一些網站是怎麼作的,並記錄了一些短信API接口防遍歷的技術實現方式。ajax
第一種方式:白名單算法
這是最簡單的一種方式,但應用場景有限,好比,在一些內部應用系統(從HR系統或其餘系統同步手機號過來驗證),此時,只須要驗證是否爲內部員工手機號,如不是,直接提示非內部員工手機號;如是,再執行短信api流控策略。api
第二種方式:驗證碼(推薦)安全
用戶點擊獲取短信驗證碼的時候,彈出圖形驗證碼進行驗證,同時發送圖形驗證碼和手機號碼到後臺驗證。post
固然,這種方式用戶體驗極差,每次都須要手動須要圖片驗證碼才能發送手機驗證碼,因而,有了進一步的優化方案,從用戶體驗和安全角度出發,可設計爲當用戶輸入3次錯誤手機驗證碼後自動彈出驗證碼。優化
還有另一種方式,採用當下比較流行的滑塊驗證或點選驗證方式,用戶體驗也會有所改善。網站
第三種方式:接口加密(不推薦)ui
前端與後臺協商好加密方式,好比md5(timestamp+telphone+salt),前臺發起請求時,同時發送 timestamp、telephone、sign參數,後臺接收這些參數,按照協商好的加密方式生成一個校驗值與sign進行對比,若是錯誤,則不處理。另外,js代碼混淆+短信api業務流控限制。
風險點:雖然作了代碼混淆,但js加密算法一旦泄漏,並非一種安全的措施,但也是一種比較容易實現的技術方案。
客戶端ajax代碼實現:
var timestamp = (new Date).getTime(); var sign = md5(timestamp+telephone+"qwertyuiopasdfghjkl"); ajax.post({ 'url': '/sms_captcha/', 'data':{ 'telephone': telephone, 'timestamp': timestamp, 'sign': sign }, ...........
以上,是三種常見的預防短信api接口遍歷的技術實現方案。
我建立了一個免費的知識星球,主要用於技術問題探討。我將這個問題發表在知識星球,獲得了很多星友的熱情迴應,如下摘錄一些星友們的見解。
@超人:限制ip有可能誤傷同一局域網下的用戶,最好是登錄後容許發送,限制用戶的發送次數
@密因:同一手機號,60秒內不能重複發送,24小時內總共發送不超過5次;2個及以上手機號,經過識別客戶端特徵,出口ip,隨機字符串,斷定是否爲同一用戶,對同一用戶使用限制措施。或者設定略高於日常請求數的基線,如平常1分鐘100個短信請求,基線設置爲150,1分鐘內超過150次以外的請求丟棄。
@Antares:限制每一個IP、賬號天天的請求頻率和數量,對請求參數作簽名校驗,防止請求重放
@Adler:在獲取驗證碼前加驗證,而後黑名單屏蔽虛擬號,限制每一個IP必定時間內的請求數和限制每一個手機號請求的總次數。
@yd:通常都是限制ip在時間段內請求次數,限制同一手機號發送次數,加圖形或滑動等驗證碼。
@Mr.周:設置請求上線 屏蔽虛擬號碼段。
@ch4ce:咱們限制了IP地址,雖然這樣不是最好的解決方案。
@Loki⚡:我我的感受,首先確保發送短信驗證碼的邏輯是正確的,而後能夠根據業務的重要程度決定是用安全產品,仍是本身開發人機識別功能。
1024:人機驗證,設備號,帆布指紋, ip。
corp0ra1:若是能夠的話,匹配用戶名?
掉到魚缸裏的貓:限制同IP請求次數。
zxt:每一個用戶一天或者一個小時只容許三個驗證碼,同ip天天只容許三個用戶獲取驗證碼。這種模式比較經常使用。
這是一個免費的星球,誠邀你的加入!