速率限制失敗,通常不是因為上限太寬鬆,而是問錯了問題。在決定「每分鐘幾次」之前,需要先回答三個問題:以誰為單位計算、計算什麼、達到上限時怎麼處理。
問題 1:以誰為單位計算?
把 IP 當主軸,對攻擊者和合法使用者都會失效
攻擊者這邊:在反向代理或 CDN 後面,應用程式看到的來源位址可能是寫在標頭裡的值。無條件信任 X-Forwarded-For,改寫標頭就足以被當成另一個人來計算。你以為在計算,其實什麼都沒算到。這個標頭能信任到什麼程度,請見 X-Forwarded-For 偽造與信任代理。
合法使用者這邊:企業 NAT 和行動網路代表許多無關的使用者共用一個位址。以 IP 為單位限制,就會限制到沒有攻擊你的人。
所以主軸應該是與行為者綁定的識別碼,例如帳號、API 金鑰、已建立的工作階段,再把 IP 疊上去當作輔助訊號。在未驗證的階段(登入前)沒有行為者可以當作鍵,這部分要靠接下來兩個問題來補。
問題 2:計算什麼?
只計算請求數的設計,擋不住單次就很昂貴的請求。OWASP 的 API Security Top 10 在 API4:2023「Unrestricted Resource Consumption(不受限制的資源消耗)」中,明列了需要上限的項目。
你在計算的東西
請求數:每分鐘 100 次 → 未達上限 ✓
↓ 但實際被消耗的是
CPU・時間
每次呼叫都全表掃描
記憶體
過大的輸入
頻寬
一萬筆紀錄
金錢
反覆的計費呼叫
= 從未觸及上限就被耗盡
- 時間與記憶體
- 執行逾時、最大記憶體配置
- 作業系統資源
- 檔案描述子數量、程序數量
- 輸入大小
- 最大上傳檔案大小、輸入參數的最大大小
- 每次請求的工作量
- 單次 API 用戶端請求中執行的操作數、每頁回傳的紀錄數
- 金錢
- 第三方服務與 API 整合的支出上限(見下文;防止財務損失的最後一道控制)
如果一次請求就回傳一萬筆紀錄、處理一個巨大的檔案,或多次呼叫按量計費的外部 API,守住「每分鐘 100 次」也什麼都保護不了。讓計算的單位對應到你要保護的東西,也就是 CPU、記憶體、頻寬、金錢。這是設計的核心。
問題 3:達到上限時怎麼處理?
這是最常被誤解的部分。越嚴格不一定越安全。
粗暴鎖定的副作用
「失敗 3 次就凍結帳號」感覺很對,但這也代表攻擊者能故意凍結別人的帳號,鎖定就變成了瞄準你自己使用者的阻斷服務工具。你擋下了暴力破解,卻同時提供了把人擋在門外的方法。
設計成「不划算」
讓嘗試變慢,而不是封鎖存取。NIST SP 800-63B 列出的做法:驗證前要求 CAPTCHA、失敗後的等待時間隨著帳號接近上限而變長、使用者以前驗證成功過的 IP 位址允許清單,以及判斷行為是否在正常範圍內(位址、地理位置、時間、瀏覽器中繼資料)的風險型或自適應技術。
NIST 的數字比你想的大:連續失敗 100 次
NIST SP 800-63B 規定「驗證方必須(SHALL)把單一帳號的連續驗證失敗次數限制在 100 次以內」。常見的「3 次就鎖定」並不是標準的要求。
為什麼 100 次就夠:只要路徑上有延遲和 CAPTCHA,要在任何有意義的時間內達到 100 次就不切實際。反過來說,只收緊次數、卻不加延遲是最糟的組合:它把合法使用者擋在外面,同時仍讓自動化攻擊快速用完嘗試次數。
同一份文件還有一個實務上的提示:驗證成功時,驗證方應該(SHOULD)忽略該使用者先前來自同一 IP 位址的失敗嘗試。計數器什麼時候歸零,也是設計的一部分。
在哪裡套用什麼
登入(暴力破解與撞庫攻擊)
以每個帳號的失敗計數為主軸,並逐步加長延遲。IP 當作輔助訊號,絕不當作唯一依據。加上多因素驗證後,密碼正確也不會立刻取得存取權,猜測就變得不划算。另外也要注意,近年的入侵越來越常是帶著有效的認證資訊進來,而不是靠猜(2026 年入侵途徑分析,英文),速率限制是必要的,但不足夠。
密碼重設與驗證信(郵件轟炸)
同時計算能觸發寄送的對象,以及寄往同一個收件地址的數量。接受別人地址的表單,會讓攻擊者能同時騷擾第三方並損害你的寄信信譽。請組合以收件地址為單位的冷卻時間、重新寄送的最短間隔,以及刪除一直未確認的紀錄(這也能減少你持有的未驗證個人資料)。重設路徑本身請見密碼重設的設計缺陷。
公開端點與 AI 功能(費用暴增)
計算成本,而不是請求數。限制輸入大小、限制每次請求執行的操作數,並且一定要設定服務商端的支出上限。OWASP 的情境中有帳單從每月 13 美元漲到 8,000 美元的例子。把按量計費的外部 API 接到公開功能時,請確保有一層在你自己的程式碼出錯時仍然有效。金鑰外洩時會發生什麼,請見金鑰被盜、帳單與帳號停權和 AI 寫的程式碼外洩 API 金鑰。
昂貴的操作(搜尋、匯出、檔案處理)
對執行時間、記憶體、上傳大小和每頁回傳的紀錄數設定明確的上限。沒有上限的地方,一次請求就能耗盡你的資源。也請在容器或 serverless 層限制記憶體、CPU 和程序數,讓使用了非預期資源的應用程式從外部被擋下。
知道何時達到上限
看不到的限制只算一半的控制。如果沒有人看得到上限正在被觸及,你既不會發現進行中的攻擊,也不會發現合法使用者被擋在外面。記錄限制被觸發的頻率,並在激增時發出通知。這就是組織的資安基準中「能察覺異常」的狀態,套用在這裡。
本站的看法:限制的目的是讓濫用不划算
把速率限制當作完全擋住攻擊的東西,最後會卡在一個無法回答的問題:幾次嘗試才安全?我們的看法不同:這是攻擊者的成本與收益問題。提高攻擊者每次嘗試的成本(時間、運算、CAPTCHA、第二因素),降低每次嘗試的預期收益(命中的機率、命中後能走多遠)。不需要把成功率降到零,只需要讓它不值得做。
所以我們偏好延遲和第二因素,而不是嚴苛的鎖定。金錢是這個推論唯一需要改變的情況:唯一可靠的上限,是位於你自己程式碼之外的支出上限。程式碼有時會出錯,請在程式碼之外放一道控制,讓錯誤也不會產生沒有上限的帳單。
資料來源(一手資料)
- NIST SP 800-63B「Digital Identity Guidelines: Authentication and Lifecycle Management」§5.2.2 Rate Limiting (Throttling) — pages.nist.gov(把連續失敗限制在 100 次以內的 SHALL;CAPTCHA、逐步加長的等待、IP 允許清單與風險型技術;成功後忽略同一 IP 先前失敗的 SHOULD)
- OWASP API Security Top 10 2023「API4:2023 Unrestricted Resource Consumption」— owasp.org(需要限制的資源、成本影響,以及設定第三方服務支出上限)
接著讀
- 比較 2026 年的重大案例:KDDI、Aflac、數位廳和 Sakura Internet 的共同點(英文)
- 實際案例:丹麥 CPR 登記資料被濫用(英文;合法用戶端的查詢權限被濫用)
- 實際案例:Baitoru 外洩事件(最多 388 萬個電子郵件地址)(英文;透過「規格缺陷」大量收集,以及每位使用者的紀錄上限)
- 前提知識:X-Forwarded-For 偽造與信任代理(「以誰計算」的基礎)
- 設計:密碼重設的設計缺陷/多因素驗證的選擇
- 費用:金鑰被盜、帳單與帳號停權/AI 寫的程式碼外洩 API 金鑰
FAQ
Q登入失敗幾次要鎖定帳號?3 次?5 次?
NIST SP 800-63B 要求驗證方把單一帳號的連續驗證失敗次數限制在 100 次以內。3 次或 5 次並不是標準的要求。同一份文件為了避免把合法使用者鎖在外面,改而要求的是:驗證前的 CAPTCHA、隨著帳號接近上限而變長的等待時間、使用者以前驗證成功過的 IP 位址允許清單,以及以風險為基礎或自適應的技術。過度的鎖定也會讓攻擊者能故意凍結別人的帳號。與其只降低次數,不如提高每次嘗試的成本。
Q以 IP 位址來限制就夠了嗎?
不夠。在反向代理或 CDN 後面,應用程式看到的位址可能不是真正的來源:無條件信任 X-Forwarded-For,攻擊者只要改寫標頭就能變成另一個用戶端,你等於什麼都沒算到。而合法使用者會透過企業 NAT 和行動網路共用位址,所以以 IP 為單位的限制也會限制到無關的使用者。請把與行為者綁定的識別碼(帳號、API 金鑰、已建立的工作階段)當作主軸,IP 只當作輔助訊號。
Q怎麼防止驗證信轟炸?
需要同時限制誰能觸發寄送,並計算寄往同一個收件地址的數量。如果你的表單接受別人的地址,攻擊者就能利用你騷擾第三方,同時損害你網域的寄信信譽。請組合以下做法:以收件地址為單位的冷卻時間、重新寄送的最短間隔,以及在一定時間後刪除一直沒有確認的紀錄,這也能減少你持有的未驗證個人資料。
Q把 AI API 放在公開功能後面時,最大的危險是什麼?
帳單。OWASP 的 API Security Top 10 在 API4:2023 Unrestricted Resource Consumption 中,列出 API 需要的限制:執行逾時、記憶體、上傳大小、每次請求的操作數,並把第三方服務的支出上限也列在其中。它的情境中有帳單從每月 13 美元變成 8,000 美元的例子。限制請求數,擋不住單次就很昂貴的操作。請設定服務商端的支出上限:那是你自己的程式碼出錯時仍然有效的唯一上限。