短信API接口在web中得到越來越多的應用,如用戶注冊,登錄,密碼重置等業務模塊都會使用手機驗證碼進行身份驗證。一般情況下,我們會采用這樣的安全策略,將短信發送頻率限制在正常的業務流控范圍內,比如,一個手機號一天最多下發10條短信,同時限制時效,驗證次數。但這樣的策略,攻擊者通過遍歷手機號,還是阻止不了短信資源被消耗的情況。
如何防止短信api接口遍歷呢?
在平時瀏覽網站的時候,我會稍微留意一些網站是怎么做的,並記錄了一些短信API接口防遍歷的技術實現方式。
第一種方式:白名單
這是最簡單的一種方式,但應用場景有限,比如,在一些內部應用系統(從HR系統或其他系統同步手機號過來驗證),此時,只需要驗證是否為內部員工手機號,如不是,直接提示非內部員工手機號;如是,再執行短信api流控策略。
第二種方式:驗證碼(推薦)
用戶點擊獲取短信驗證碼的時候,彈出圖形驗證碼進行驗證,同時發送圖形驗證碼和手機號碼到后台驗證。
當然,這種方式用戶體驗極差,每次都需要手動需要圖片驗證碼才能發送手機驗證碼,於是,有了進一步的優化方案,從用戶體驗和安全角度出發,可設計為當用戶輸入3次錯誤手機驗證碼后自動彈出驗證碼。
還有另外一種方式,采用當下比較流行的滑塊驗證或點選驗證方式,用戶體驗也會有所改善。
第三種方式:接口加密(不推薦)
前端與后台協商好加密方式,比如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每天只允許三個用戶獲取驗證碼。這種模式比較常用。
這是一個免費的星球,誠邀你的加入!