---
title: SR-07 可用性與資源
eyebrow: Guidant AI 資安檢視總報告 · 安全需求（SR）
h1: SR-07 可用性與資源
subtitle: 每個入口都有上限
lede: 任何接受外部輸入的入口，都要有大小、速率、逾時、並行數的上限，失敗時不拖垮其他功能。這一章 **9 條**：前門、外部 AI、外部呼叫、背景工作、即時連線、資料庫、agent 暫存、掃描、Redis 與檔案儲存。4 條有掃描實例、5 條是標準做法。
chips:
  - { text: "9 條", kind: accent }
  - { text: "掃描驗證 4", kind: ok }
  - { text: "標準做法 5", kind: plain }
---

> 讀法見[總表](SR-00-overview.html)。每條六欄：要求／為什麼／適用連線／對應威脅／驗證方式／來源。現況不在這裡，看[符合性矩陣](SR-matrix.html)。

## 這一章管什麼

「讓服務停擺」不需要攻破任何東西——一個特製請求、幾個分頁、一份壓縮炸彈就夠。系統有三種容易被拖垮的地方：**共用的處理程序**（前門、聊天框、背景 worker 一起吃同一台機器）、**共用的資料層**（整張表一次撈出來、交易開著一列列讀）、**客戶機房裡的 agent**（磁碟、記憶體小，停擺就是該客戶所有檢測停擺）。本章每條都是「某個入口少了某道上限」。

| # | 要求 | 來源 |
|---|---|---|
| SR-07.1 | 前門有請求大小與速率上限，免登入端點另有濫用上限與告警 | 標準做法 |
| SR-07.2 | 外部 AI 呼叫有長度、逾時、次數、額度四道上限 | 掃描驗證 |
| SR-07.3 | 所有外部呼叫有逾時，失敗不拖垮本地操作 | 標準做法 |
| SR-07.4 | 背景工作有去重、並行與深度上限，佇列有租約與重撿 | 掃描驗證 |
| SR-07.5 | 即時連線有同時連線數與事件速率上限，跨來源白名單與 HTTP 對齊 | 標準做法 |
| SR-07.6 | 資料庫做的事有上限 | 掃描驗證 |
| SR-07.7 | agent 側暫存有容量上限與清理，磁碟低水位告警 | 標準做法 |
| SR-07.8 | 掃描可即時取消、有逾時，預設強度保守 | 標準做法 |
| SR-07.9 | Redis 不持久化、不留免密入口，衍生檔同生共死 | 掃描驗證 |

---

## SR-07.1 前門有請求大小與速率上限，免登入端點另有濫用上限與告警 {#sr-07-1}

| 欄位 | 內容 |
|---|---|
| **要求** | 前門**必須**對所有請求設大小上限與每來源速率上限，**不得**以「交後端各自把關」代替；不需登入的端點（OAuth 回呼、Drive webhook、忘記密碼、驗證碼）**必須**另有濫用上限：失敗次數有速率限制並告警，不讓人拿這類端點對 Redis 或日誌灌流量 |
| **為什麼** | 前門不擋時，單一來源用大量或大體積請求就能耗盡後端；免登入端點任何人可無限次打，Redis 查詢與日誌會被灌滿，真正的異常訊號被淹沒 |
| **適用連線** | [C01](../connections/C01-browser-to-frontdoor.html) 瀏覽器 → 前門、[C04](../connections/C04-browser-to-api-drive-oauth.html) 瀏覽器 → api（Drive OAuth 回呼）、[C14](../connections/C14-api-to-google-drive.html) api → Google Drive；推及：[C02](../connections/C02-frontdoor-to-api.html) 前門 → api（前門到 api 的所有端點共用前門上限） |
| **對應威脅** | C01 [T2 驗身分之前的處理被餵特製內容，把全站卡死](../connections/C01-browser-to-frontdoor.html) 🟠、C14 [T5 從不需登入的通知入口與驗憑證按鈕下手](../connections/C14-api-to-google-drive.html) ⚪ |
| **驗證方式** | 對任一端點送超過上限的內容，前門必須回 413 且請求不到後端；單一來源在一分鐘內對回呼與 webhook 端點連送超過上限次數，之後的請求必須被限速並產生一筆告警 |
| **來源** | 標準做法：C01 D7◇、C04 D4◇、C14 D7◇ |

## SR-07.2 外部 AI 呼叫有長度、逾時、次數、額度四道上限 {#sr-07-2}

| 欄位 | 內容 |
|---|---|
| **要求** | 呼叫外部 AI 之前**必須**有四道上限：訊息長度（在路由最外層擋，不等進服務才量）、呼叫逾時（外部回得慢時系統自己放棄）、每人每分鐘次數（跨行程累計，不得各行程各算各的）、每租戶與每人每日美元額度；任一道超限**必須**回明確錯誤 |
| **為什麼** | 聊天框是任何登入員工都能開的入口：開四到八個分頁各送一則超大訊息，處理程序被全部佔住，其他人連登入畫面都打不開；或把公司共用的 AI 額度燒光變成帳單 |
| **適用連線** | [C13](../connections/C13-api-to-external-ai.html) api → 外部 AI |
| **對應威脅** | C13 [T3 用聊天框把處理程序佔光、把額度燒光](../connections/C13-api-to-external-ai.html) 🟡 |
| **驗證方式** | 單一帳號同時開 8 個分頁各送超長訊息，其他帳號登入與其他頁面必須仍正常回應；一分鐘內超過次數上限必須被拒；模擬外部 AI 不回應，請求必須在逾時內失敗而非無限等待；累計用量超過每日額度後必須被拒 |
| **來源** | 掃描驗證：C13 D3（實例 [M14-1](../STRIDE/D-denial-of-service.html#m14-1)） |

## SR-07.3 所有外部呼叫有逾時，失敗不拖垮本地操作 {#sr-07-3}

| 欄位 | 內容 |
|---|---|
| **要求** | 系統對外部服務（AI、GitLab／GitHub、Discord、Telegram、授權簽發站、Google Drive、SMTP）的每一次呼叫**必須**設逾時；外部失敗或過慢**不得**使本地操作失敗或變慢（背景發送要有逾時，不得讓執行緒永遠掛著；清單頁不得因外部慢而慢）；失敗**必須**有紀錄 |
| **為什麼** | 沒設逾時的外部呼叫會讓處理程序或執行緒永遠掛著，外部服務一掛，本地功能跟著累積卡死直到整個服務停擺 |
| **適用連線** | [C15](../connections/C15-api-to-issue-tracker.html) api → 問題追蹤（GitLab／GitHub）、[C16](../connections/C16-api-to-chat-webhook.html) api → 聊天 webhook（Discord／Telegram）；推及：[C10](../connections/C10-api-to-smtp.html) api → 客戶 SMTP（寄信）、[C12](../connections/C12-api-to-siem.html) api → 客戶 SIEM（日誌轉送）、[C13](../connections/C13-api-to-external-ai.html) api → 外部 AI（AI）、[C14](../connections/C14-api-to-google-drive.html) api → Google Drive（Google Drive）、[C18](../connections/C18-api-to-license-center.html) api → 授權簽發站（授權簽發站） |
| **對應威脅** | 無掃描實例（標準做法） |
| **驗證方式** | 把各外部位址換成一個接受連線但不回應的測試伺服器，各功能必須在設定的逾時內返回錯誤；同時開清單頁，頁面回應時間不得隨外部延遲增加（有外部資料的清單可降級顯示） |
| **來源** | 標準做法：C15 D5◇、C16 D4◇ |

## SR-07.4 背景工作有去重、並行與深度上限，佇列有租約與重撿 {#sr-07-4}

| 欄位 | 內容 |
|---|---|
| **要求** | 背景工作入列**必須**有去重（同一資源同類工作不重複排）、並行上限、排隊深度上限；每條工作**必須**有資源上限（記憶體、處理時間、外部程序數）；佇列**必須**有租約與心跳、死掉的 worker 的單**必須**被重撿、重試**必須**有上限、停機時**必須**做完手上的單；多 worker **不得**搶同一張單 |
| **為什麼** | 有權限的帳號對同一資源連打幾百次「重新解析」，每次開一條吃 50MB 記憶體與最長 15 分鐘外部程式的背景工作，同一台機器上所有客戶一起變慢；單卡死而沒有租約，就永遠占著位置 |
| **適用連線** | [C09](../connections/C09-api-to-worker.html) api → worker（背景工作）；推及：[C19](../connections/C19-api-to-profile-url.html) api → 規則包網址（規則包解析工作）、[C08](../connections/C08-worker-to-sandbox.html) worker → 沙箱（拆檔）（拆檔工作） |
| **對應威脅** | C09 [T3 入列沒有上限、沒有去重，用背景工作把主機打掛](../connections/C09-api-to-worker.html) 🟡 |
| **驗證方式** | 對同一版規則包連送 100 次重新解析，佇列中該類工作不得超過去重後的上限，且並行數不得超過設定值；殺掉持單中的 worker，單必須在租約逾時後被另一 worker 撿起；單連續失敗必須在重試上限後標為失敗，不再重排 |
| **來源** | 掃描驗證：C09 D4（實例 [M03-10](../STRIDE/D-denial-of-service.html#m03-10)、[M07-8](../STRIDE/D-denial-of-service.html#m07-8)、[M24-15](../STRIDE/D-denial-of-service.html#m24-15)）；標準做法：C09 D7◇ |

## SR-07.5 即時連線有同時連線數與事件速率上限，跨來源白名單與 HTTP 對齊 {#sr-07-5}

| 欄位 | 內容 |
|---|---|
| **要求** | 即時連線（socket）**必須**限制每個使用者同時連線數與每秒事件數；跨來源白名單**必須**與 HTTP 側一致，只接受本站來源，**不得**預設放行所有來源 |
| **為什麼** | 長連線加上「每個事件寫一次資料庫」的設計，單一帳號開大量連線或高頻 `update` 就能占滿 socketio 行程與資料庫寫入；來源不限時，任何網站的頁面都能對已登入使用者發起連線 |
| **適用連線** | [C03](../connections/C03-frontdoor-to-socketio.html) 前門 → socketio |
| **對應威脅** | 無掃描實例（標準做法） |
| **驗證方式** | 同一帳號建立超過上限數的連線，超出的必須被拒；單一連線一秒內送超過上限的 `update` 事件，超出的必須被丟棄或限速；從不在白名單內的 Origin 發起交握必須被拒 |
| **來源** | 標準做法：C03 D6◇、C03 D5◇ |

## SR-07.6 資料庫做的事有上限 {#sr-07-6}

| 欄位 | 內容 |
|---|---|
| **要求** | 資料庫查詢與匯入**必須**有上限：每頁筆數在共用分頁格式設上限（超過即截到上限）；連線設 `statement_timeout`；讀檔解析**必須**用串流、連續空白視為檔尾、列數有上限；寫入端**必須**拒絕空內容；讀取端遇一筆壞資料**不得**使整份查詢失敗 |
| **為什麼** | 任何登入帳號把「一頁幾筆」改成超大數字就能讓資料庫整張表撈出；幾 KB 的稽核表在第 20 萬列填一格，匯入就從頭讀到那裡且整段交易一直開著；一筆空白範本讓所有人打開清單頁都 500 |
| **適用連線** | [C05](../connections/C05-api-to-database.html) api → 資料庫；推及：[C02](../connections/C02-frontdoor-to-api.html) 前門 → api（所有分頁清單與匯入端點） |
| **對應威脅** | C05 [T6 一個請求讓資料庫做太多：整張表撈出來、交易開著一列列讀**（4 條）](../connections/C05-api-to-database.html) 🟡 |
| **驗證方式** | 對任一清單端點送 `page_size` 超大值，回傳筆數必須被截到上限；匯入一份在極遠列有內容的小檔，必須在列數上限處中止、交易不得長時間開著；存一筆空內容範本必須被拒；人為在表中放一筆格式損壞的資料，清單頁其餘資料必須仍能顯示 |
| **來源** | 掃描驗證：C05 D6（實例 [M04-7](../STRIDE/D-denial-of-service.html#m04-7)、[M12-3](../STRIDE/D-denial-of-service.html#m12-3)、[M06-8](../STRIDE/D-denial-of-service.html#m06-8)、[M19-3](../STRIDE/D-denial-of-service.html#m19-3)） |

## SR-07.7 agent 側暫存有容量上限與清理，磁碟低水位告警 {#sr-07-7}

| 欄位 | 內容 |
|---|---|
| **要求** | agent 的物件儲存 bucket、工作目錄與 cache **必須**有容量上限與清理機制（已被雲端取回的檔定期清）；可用磁碟低於門檻**必須**告警；agent 對收到的 probe 請求**必須**自己再守一道上限（單次主機數、逾時、併發數），**不得**只信雲端的限制 |
| **為什麼** | 客戶機房的 agent 磁碟小，沒有容量上限時等著就會滿，agent 寫不進報告、掃描全部失敗，雲端只看到「上傳失敗」；雲端的限制只是一道，雲端出錯或被冒充時 agent 自己沒有第二道 |
| **適用連線** | [C22](../connections/C22-agent-to-seaweedfs.html) agent → SeaweedFS、[C23b](../connections/C23b-agent-local-processes.html) agent 本機程序、[C21](../connections/C21-api-to-agent-dataplane.html) api → agent 資料面（:8443） |
| **對應威脅** | C22 [T3 塞爆磁碟讓 agent 停擺](../connections/C22-agent-to-seaweedfs.html)（無掃描實例）、C23b [T3 特製壓縮包或巨型 repo 把 agent 主機撐爆](../connections/C23b-agent-local-processes.html)（無掃描實例）、C21 [T3 測試連線連到哪，由按的人自己填——代理程式變成內網探測器](../connections/C21-api-to-agent-dataplane.html) 🟡、C21 [T1 冒充雲端打進客戶機房](../connections/C21-api-to-agent-dataplane.html) 🔴 |
| **驗證方式** | 把 bucket 寫到配額上限，之後的寫入必須被拒並產生告警；把磁碟剩餘壓到門檻以下必須觸發告警；對 agent 資料面送超過單次主機數上限的 probe，必須在 agent 端被拒 |
| **來源** | 標準做法：C22 D4◇、C23b D6◇、C21 D5◇ |

## SR-07.8 掃描可即時取消、有逾時，預設強度保守 {#sr-07-8}

| 欄位 | 內容 |
|---|---|
| **要求** | 每一次掃描**必須**可即時取消並有逾時；預設強度**必須**保守：Nmap 預設 connect 掃描、**不得**預設 SYN 全埠；OpenVAS **不得**預設會打掛設備的 config；ZAP active scan **必須**由使用者明確勾選才開 |
| **為什麼** | 掃描流量對老舊印表機、網路設備、工控系統就是攻擊，預設太重會直接打掛客戶內網設備，而且是「我們的產品」造成的；停不掉的掃描讓傷害持續擴大 |
| **適用連線** | [C25](../connections/C25-engine-to-targets.html) 掃描引擎 → 目標 |
| **對應威脅** | C25 [T2 掃描流量打掛內網脆弱設備](../connections/C25-engine-to-targets.html)（無掃描實例）、C25 [T3 掃描流量觸發客戶自己的防禦，agent 被封](../connections/C25-engine-to-targets.html)（無掃描實例） |
| **驗證方式** | 新建一個未調整任何選項的任務，檢查實際下發的引擎參數：Nmap 不得為 SYN 全埠、OpenVAS 不得為會打掛設備的 config、ZAP 不得啟用 active scan；掃描進行中按取消，目標端的探測流量必須在數秒內停止；任務超過逾時必須被中止 |
| **來源** | 標準做法：C25 D5◇、C25 D3◇ |

## SR-07.9 Redis 不持久化、不留免密入口，衍生檔同生共死 {#sr-07-9}

| 欄位 | 內容 |
|---|---|
| **要求** | Redis **必須**不對外、不持久化、不留免密入口；檔案的衍生檔（預覽轉出的 PDF）**必須**在主檔刪除時一併清除，物件儲存與本機儲存走同一套；切換儲存後端時**不得**丟舊檔——每個檔**必須**記錄自己躺在哪種後端、讀取時借對應設定 |
| **為什麼** | Redis 持久化或免密時，暫存內容（AI 對話、共編名單）落到磁碟或被同網段的人直接讀寫；衍生檔不跟著刪，使用者以為已刪除的敏感內容仍留在硬碟；切換後端丟舊檔則證據遺失 |
| **適用連線** | [C06](../connections/C06-api-to-redis.html) api → Redis、[C07](../connections/C07-api-to-file-storage.html) api → 檔案儲存 |
| **對應威脅** | C07 [T5 刪了主檔，預覽時轉出的 PDF 還留在儲存裡](../connections/C07-api-to-file-storage.html) ⚪ |
| **驗證方式** | 從主機外對 Redis 埠連線必須被拒；不帶密碼連 Redis 必須被拒；確認 Redis 設定無持久化且重啟後無舊資料；上傳並預覽一份檔後刪除，儲存中該檔的主檔與轉出的 PDF 必須都不存在；切換儲存後端後，切換前上傳的檔必須仍可下載 |
| **來源** | 掃描驗證：C07 D5（實例 [M02-9](../STRIDE/I-information-disclosure.html#m02-9)）；標準做法：C06 D2◇、C07 D8◇ |

---

*來源：[連線頁](../connections/C01-browser-to-frontdoor.html)的防線（D）；去重對照在 `requirements/_drafts/D-to-SR.md`。*
