HTTP協議掃盲(五)HTTP請求防篡改


相關鏈接:

http://www.cnblogs.com/ziyi--caolu/p/4742577.html

請求防重放:http://www.2cto.com/kf/201612/573045.html

登錄防重放:http://huangqiqing123.iteye.com/blog/2033014

一、概念和定義

1、什么是重放攻擊?

我們在設計接口的時候,最擔心一個接口被別有用心的用戶截取后,用於重放攻擊。重放攻擊是什么呢?就是把請求被原封不動地重復發送,一次,兩次...n次。

2、重放攻擊造成的后果

一般的請求被提交到后台執行,先會經過【頁面驗證】后提交給【后台邏輯】,提交給【后台邏輯】過程中請求可能會被被攔截,

  • 如果這個【后台邏輯】是插入數據庫操作,就很容易造成多條重復的數據插入數據庫。
  • 如果這個【后台邏輯】是查詢數據庫操作,就可能導致反復查詢,數據庫被堵住等情況。

所以,我們需要一種防重放的機制來做請求驗證。

二、解決方案

1、客戶端(攜帶timestamp+nonce)

我們常用的防止重放的機制是使用timestamp和nonce來做的重放機制。

1.1、timestamp

timestamp用來表示請求的當前時間戳,這個時間要事先和服務器時間戳校正過。我們預期正常請求帶的時間戳會是不同的,如:假設正常人每秒至多會做一個操作。

每個請求攜帶的時間戳不能和當前時間距離很近,即不能超過規定時間,如60s。這樣請求即使被截取了,也只能在有限時間(如:60s)內進行重放,過期就會失效。

1.2、nonce

僅僅提供timestamp還是不夠的,我們還是提供給攻擊者60s的可攻擊時間了。要避免60秒內發生攻擊,我們還需要使用一個nonce隨機數。

nonce是由客戶端根據隨機生成的,比如 md5(timestamp+rand(0, 1000),正常情況下,在短時間內(比如60s)連續生成兩個相同nonce的情況幾乎為0。

2、服務端(驗證時間是否超限,檢查簽名)

服務端第一次在接收到這個nonce的時候做下面行為:

1 去redis中查找是否有key為nonce:{nonce}的string

2 如果沒有,則創建這個key,把這個key失效的時間和驗證timestamp失效的時間設置一致,比如是60s。

3 如果有,說明這個key在60s內已被使用過了,這個請求就可以判斷為重放請求。

3、方案流程 

http://www.xxxx.com?userId=123&userName=zhangsan&timestamp=1480556543&nonce=43f34f33&sign=80b886d71449cb33355d017893720666

在這個請求中,userId和userName是真正需要傳遞的業務參數,timestamp,nonce,sign都是為了簽名和防重放使用。

timestamp是發送請求時間,nonce是隨機串,sign是對uid,timestamp,nonce(對於一些rest風格的api,建議業務參數一起簽名)。

服務端接到這個請求的處理邏輯:

  • 先驗證sign簽名是否合理,證明請求參數沒有被中途篡改
  • 再驗證timestamp是否過期,證明請求是在最近60s被發出的
  • 最后驗證nonce是否已經有了,證明這個請求不是60s內的重放請求

4、方案分析

我們將每次請求的nonce參數存儲到一個“集合”中,可以json格式存儲到緩存中。

 每次處理HTTP請求時,首先判斷該請求的nonce參數是否在該“集合”中,如果存在則認為是非法請求。

我們在timestamp方案的基礎上,加上nonce參數,因為timstamp參數對於超過60s的請求,都認為非法請求,所以我們只需要存儲60s的nonce參數的“集合”即可。

nonce的一次性可以解決timestamp參數60s的問題,timestamp可以解決nonce參數“集合”越來越大的問題。 


免責聲明!

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



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