防止重復請求攻擊


今天發現自己項目一個漏洞:先為一賬戶充值100元,然后瞬間發送10次提現請求(都是提現100,提現接口是有做余額不足校驗的),其中大約有四五次都是成功的,剩下的會報余額不足。期望是,只有一次可以成功完成提現,分析到能部分請求能通過余額不足校驗原因是,由於是瞬間發出的提現請求,這些請求中拿到的余額數據都是余額扣減之前的數據。

以上場景可以提煉出兩個關鍵步驟:

  1. 查詢余額並校驗,select * from account where user_id = 123;
  2. 扣減余額並支付,update account set balance...

根據以上步驟,可知:1.在兩條SQL語句執行的中間這段時間,由於重復請求攻擊,可能會出現多次請求的第一步操作成功,並繼續執行第二步,最后導致資金損失。2.由於第一步操作是查詢操作,沒有數據庫會限制重復讀取數據,數據庫層面是沒有可能解決這個問題的,所以不用在這個上面浪費時間。

目前的解決方案是:為接口上鎖。已經有人做了輪子,比如redis-lock。以用戶ID為key,某個uuid為值。將類似提現這樣的接口上鎖。同一用戶在訪問添加了該中間件的接口時,第一次沒有執行完畢,拒絕執行第二個請求。第一次執行完畢時,釋放鎖,即清除redis緩存的鍵值對。同時可設定,緩存時長,以防中途宕機,鎖未釋放等問題。具體實現可以參考npm包redis-lock文檔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM