Guidant AI 資安檢視總報告 · 安全需求(SR)

SR-07 可用性與資源

每個入口都有上限

任何接受外部輸入的入口,都要有大小、速率、逾時、並行數的上限,失敗時不拖垮其他功能。這一章 9 條:前門、外部 AI、外部呼叫、背景工作、即時連線、資料庫、agent 暫存、掃描、Redis 與檔案儲存。4 條有掃描實例、5 條是標準做法。

9 條 掃描驗證 4 標準做法 5

讀法見總表。每條六欄:要求/為什麼/適用連線/對應威脅/驗證方式/來源。現況不在這裡,看符合性矩陣。

§1

這一章管什麼

「讓服務停擺」不需要攻破任何東西——一個特製請求、幾個分頁、一份壓縮炸彈就夠。系統有三種容易被拖垮的地方:共用的處理程序(前門、聊天框、背景 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 不持久化、不留免密入口,衍生檔同生共死 掃描驗證

§2

SR-07.1 前門有請求大小與速率上限,免登入端點另有濫用上限與告警

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

SR-07.2 外部 AI 呼叫有長度、逾時、次數、額度四道上限

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

SR-07.3 所有外部呼叫有逾時,失敗不拖垮本地操作

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

SR-07.4 背景工作有去重、並行與深度上限,佇列有租約與重撿

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

SR-07.5 即時連線有同時連線數與事件速率上限,跨來源白名單與 HTTP 對齊

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

SR-07.6 資料庫做的事有上限

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

SR-07.7 agent 側暫存有容量上限與清理,磁碟低水位告警

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

SR-07.8 掃描可即時取消、有逾時,預設強度保守

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

SR-07.9 Redis 不持久化、不留免密入口,衍生檔同生共死

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

來源:連線頁的防線(D);去重對照在 requirements/_drafts/D-to-SR.md。