Replay Attack
Replay Attack 的核心概念是攻擊者不需要偽造內容,只要把一個原本合法的請求整包重送就能再次生效。它成立的條件是驗證機制只檢查「這個請求是否合法」而不檢查「這個請求是否已經被處理過」——Message Authentication 的驗證值對重送的內容照樣吻合,因為內容確實沒有被改動。收斂它依賴新鮮度判斷,時間基準的偏差範圍見 Clock Skew。
概念位置
Replay Attack 位在完整性驗證與去重之間的縫隙。完整性機制回答「內容有沒有被改」,重放攻擊的答案是「沒有」,所以它從完整性這一側看起來完全正常。它與 Idempotency Key 處理的是不同來源的同一個現象:冪等鍵針對的是正常呼叫方的重試,防重放針對的是攻擊者刻意重送,前者要讓重複請求安全地不產生第二次副作用,後者要讓重複請求根本不被受理。
它與 Token Revocation 的差異在時間軸。撤銷處理的是憑證在未來失效,重放處理的是過去某一刻的合法請求在現在被複用——即使憑證仍然有效,那個請求也不該被執行第二次。
可觀察訊號與例子
需要正視重放設計的訊號是請求帶有金額、狀態轉移或發送動作,而驗證素材裡沒有任何隨每次請求變動的欄位。轉帳請求被重送一次就是第二筆轉帳,通知請求被重送就是第二封信。
常見的失效是防護做了一半:驗證值涵蓋了時間戳,接收端卻沒有檢查時間戳的新鮮度。這種情況在功能測試裡完全正常,因為測試不會重送舊請求。
另一種失效是新鮮度窗口設得比實際需要寬。窗口內的重送仍然通得過,所以窗口有多長,攔截到的請求就有多長的可用期。實際的時鐘偏移是秒級而窗口設在分鐘級時,多出來的部分全部是攻擊者的可用時間。
設計責任
設計時要讓每個請求帶一個不重複的識別值,接收端記錄已處理過的識別值並在窗口內拒絕重複的。識別值與時間戳都要進驗證素材,否則攻擊者可以自行替換。
窗口的下界由兩個量的較大者決定:雙方時鐘的 偏移 上界,以及推送方的最大重試退避間隔——後者在時間戳於事件產生時簽的設計下常常主導,因為整串重試共用同一個時間戳。上界則由儲存量反推:窗口越長,接收端要保留的已處理識別值就越多。兩端的完整換算與交叉時的處置見 7.35 簽章對接的驗證收斂。
拒絕的原因要能區分「驗證值不符」與「時間戳過期」與「識別值重複」。前兩者指向規格或密鑰不一致、以及時鐘偏移。識別值重複則要再分一次:它的絕大多數來源是推送方的正常重試,所以它是「需要調查」的訊號而非「已經在被攻擊」的訊號,處置前要看來源位址與時間分布。
哪些端點需要這一格、窗口長度兩端怎麼換算、以及這一格在功能測試裡為什麼不會被發現,判讀見 7.35 簽章對接的驗證收斂。