搜尋文件

輸入關鍵字,搜尋標題與正文。

    Web 應用資安文件 12/13

    限流、配額與資源耗盡防護

    本文提要

    即使每一個請求都通過了格式檢查與權限驗證,只要系統允許外部在短時間內無上限地觸發登入驗證、全文搜尋、報表匯出或寄送驗證信,少數自動化腳本或失控的無限重試就能耗盡 CPU、資料庫連線與第三方配額,讓正常使用者無法讀寫自己的筆記。 這類無限制分配資源的風險,在常見弱點分類中稱為〈CWE-770:Allocation of Resources Without Limits or Throttling〉。

    18px · 寬鬆行距

    閱讀設定

    排版預覽 · 示範文字(可捲動)

    檔案與目錄

    Linux 以一棵從根目錄 / 開始的樹狀結構組織檔案。目錄用來整理檔案,也可以包含其他目錄。

    pwd
    ls -la /home
    18px

    16、18、20、22px;隨瀏覽器文字大小縮放。

    欄寬套用於背景文章;此處預覽字級與行距。手機正文自動配合螢幕。

    文件與本文目錄
    本主題文件

    即使每一個請求都通過了格式檢查與權限驗證,只要系統允許外部在短時間內無上限地觸發登入驗證、全文搜尋、報表匯出或寄送驗證信,少數自動化腳本或失控的無限重試就能耗盡 CPU、資料庫連線與第三方配額,讓正常使用者無法讀寫自己的筆記。 這類無限制分配資源的風險,在常見弱點分類中稱為〈CWE-770:Allocation of Resources Without Limits or Throttling〉。

    先備概念見信任邊界與威脅思考、登入、Cookie 與 Session與逾時、重試與冪等性。 查證日期:2026-11-03。依 OWASP Denial of Service/Authentication Cheat Sheet、MITRE CWE-770 與 RFC 6585 整理。 本次僅查證文件,未部署限流器或執行壓力測試;以下為自創的筆記服務情境。

    為什麼語法合法的請求也能耗盡服務容量:非對稱成本

    Web 應用常存在非對稱成本(asymmetric cost):攻擊者或異常客戶端送出一個幾百位元組的 HTTP 請求非常便宜,但伺服器為了回應這個請求,卻可能付出數百倍的運算與 I/O 代價。 參考 OWASP Denial of Service Cheat Sheet。

    圖解
    外部送出 1 個簡短請求(很低成本)
        │
        ├─→ POST /login       :執行慢速密碼雜湊驗證(消耗大量 CPU)
        ├─→ POST /forgot-pwd  :發送外部重設信或簡訊(消耗第三方配額與費用)
        └─→ GET  /notes/export:掃描數萬筆筆記並打包壓縮(消耗記憶體、資料庫連線與磁碟 I/O)
    

    因此,可用性與資源保護不能只靠最外層網路防火牆過濾大量封包,還必須在應用層針對不同端點的成本與業務風險設計限流(rate limiting)、配額(quota)與輸入大小上限。

    限流不能只看單一來源 IP:依操作選擇識別維度

    若所有限流規則都只寫「每個來源 IP 每分鐘最多 N 次」,在真實網路環境中很快會遇到兩個反效果:

    • 誤擋共享 IP 的正常使用者:公司、學校或行動網路常透過 NAT 讓數百人共用同一個對外 IP;若門檻太低,一個部門多人同時使用筆記服務就會集體被擋。
    • 擋不住分散式來源:攻擊者使用多個代理節點輪流發送請求時,單一 IP 的速率看似正常,但目標帳號或後端資料庫已經承受很大壓力。

    實務上應依端點性質組合多個維度(keying):

    表格・3 欄 4 列
    端點或操作類型要防範的主要風險建議組合的限流與配額維度
    登入與驗證碼檢查(POST /login)單一帳號暴力猜密碼、或跨大量帳號的憑證填充(credential stuffing)同時檢查「來源 IP 速率」與「目標帳號識別(如電子郵件)速率」,並設全站總保護上限
    寄送重設密碼信/驗證簡訊密集發送訊息干擾特定收件位址、耗盡第三方寄信費用依「目標收件位址/門號冷卻時間」、「來源 IP」與「每小時全站發送配額」共同限制
    已登入的一般筆記讀寫單一失控腳本高頻輪詢或塞滿佇列依「已驗證的 user_id/API key」限制突發速率與每分鐘請求數
    高成本匯出、轉檔與批次搜尋少數大型請求占滿工作執行緒與資料庫連線池依「user_id 並行工作數上限(如同時最多 1 個匯出工作)」加上單次查詢分頁與大小限制

    此外,若應用伺服器位於反向代理或 CDN 後方,直接讀取 TCP 連線的來源位址只會拿到代理伺服器自己的 IP(導致全站所有使用者被算成同一個 IP)。 必須比照〈TLS、HTTPS 與傳輸安全邊界〉的原則,只在確認請求來自受控代理時,才採信代理寫入的客戶端 IP 標頭。

    登入防暴力破解與「帳號鎖定」的副作用

    保護登入端點時,若設計成「只要連續輸入錯誤密碼 5 次,就將該帳號永久鎖定直到人工解鎖」,攻擊者只要拿到一份公開的使用者電子郵件清單,就能故意對每個帳號連送 5 次錯誤密碼,讓大批正常使用者全部無法登入,形成帳號鎖定型阻斷服務(Account Lockout DoS)。 參考 OWASP Authentication Cheat Sheet:Protect Against Automated Attacks。

    較穩健的緩解組合包括:

    1. 以時間窗冷卻與漸進延遲取代永久鎖死:在短時間失敗達門檻後,僅對該帳號或來源組合實施短暫冷卻(或要求額外驗證挑戰),讓合法擁有者稍候或透過安全管道仍能恢復使用。
    2. 限制密碼輸入最大長度:慢速密碼雜湊演算法本來就會刻意消耗 CPU;若允許傳入數 MB 的超長字串進入雜湊計算,單一請求就可能長時間占用運算資源,應在進入雜湊前先檢查合理長度上限。
    3. 不以明顯差異洩漏帳號是否存在:重設密碼或登入失敗時,對外的回應訊息與處理流程應盡量一致,避免讓自動化工具直接試出哪些電子郵件已註冊。

    把成本擋在昂貴資源之前,並回傳明確的退避信號

    限流與資源保護的順序應該是越便宜的檢查越早做:

    1. 在進入資料庫與業務邏輯前先擋下超額請求:在閘道或 HTTP 接收層先限制請求本體(body)大小、JSON 巢狀深度與單頁查詢上限(limit 最大值,見〈集合查詢設計〉)。
    2. 以非同步佇列隔離昂貴工作:像「匯出全部筆記 PDF」這類耗時任務,不應占著同步 HTTP 連線與資料庫交易等待完成,而應檢查該使用者的進行中工作配額後放入背景佇列。
    3. 使用明確的 429 Too Many Requests 與退避契約: 當請求觸發限流時,HTTP 層可回傳 429 Too Many Requests,並視情境附上 Retry-After 標頭告知客戶端應等待多久再重試。參考 RFC 6585 §4:429 Too Many Requests。 同時,自己的前端與 SDK 在收到 429 或 503 時,必須遵守〈逾時、重試與冪等性〉的指數退避與抖動(backoff with jitter),不能立刻無延遲重送,否則會在系統恢復瞬間再次製造重試風暴。

    相關文件