Guidant AI 資安檢視總報告 · 連線清單

C24 代理程式 → 規則包網址(url 型檢測基準,HTTPS)

客戶用「網址」建檢測基準時,派掃描的代理程式自己去那個網址把規則包抓下來、交給檢測引擎執行的那條線。規則包是程式(InSpec 的 Ruby DSL),抓到什麼就跑什麼。雲端那頭已經先抓過一次、算了指紋(C19),但代理程式這頭沒有拿那個指紋來比對。這一頁回答:這條線怎麼連、哪些功能走它、它帶來什麼威脅、駭客怎麼打、我們要怎麼防、目前做到哪。

url 型基準才有 抓到什麼就執行・不比指紋 威脅 3 種 掃描命中 1 條

這一頁怎麼來的:DFD Level 0 把產品運作時的連線編成 C01~C25;STRIDE 六頁每一條問題都標了發生在哪幾條線。這裡以連線為單位整理。命中 1 條,另兩種手法依特性補(表內標明)。個別問題修了沒不在這頁講。

§1

一、連線圖

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB'}}}%%
flowchart LR
    ADMIN(["👤 客戶管理員<br/>填規則包網址"])
    subgraph MAIN["🏠 主系統"]
        API["guidant-api<br/>C19:抽取一次<br/>只收 https・擋內網・限 50MB<br/>算 sha256 落庫"]
    end
    URL(["🌐 規則包網址<br/>(客戶或第三方的伺服器)"])
    MITM(["🕵 路徑上的人<br/>或網址的主人"])
    subgraph AGENTBOX["🏢 客戶機房"]
        direction TB
        AG["evidence-agent<br/>收到 {url, sha256}"]
        CINC["cinc-auditor<br/>自己抓 url・載入即執行<br/>(不比 sha256)"]
        AG -- "url 原樣交出" --> CINC
    end
    HOSTS(["受檢主機(C23)"])
    ADMIN -- "C02" --> API
    API -. "C19 · https" .-> URL
    API -- "C20 · 派工帶 {url, sha256}" --> AG
    CINC == "C24 · https(舊基準可能 http)" ==> URL
    MITM -. "換內容" .-> CINC
    CINC -- "帶客戶帳密去跑規則" --> HOSTS
    classDef ext fill:#FBFCFC,stroke:#9AA8AA,stroke-dasharray:3 2
    classDef open fill:#FDECEC,stroke:#C0392B
    class ADMIN,URL,MITM,HOSTS ext
    class CINC open
C24 — 代理程式抓 url 型規則包。雲端建基準時先抓一次(C19:只收 https、擋內網 IP、限 50MB、算 sha256 落庫),派工時把 url 與 sha256 一起下發;代理程式拿到 url 原樣交給 cinc-auditor 自己去抓,sha256 沒用上。紅色:這一跳沒有完整性比對、不經 agent 自己的下載器。
§2

二、這條線怎麼連

項目 現況
誰 → 誰 客戶機房的 evidence-agent(實際是它起的 cinc-auditor 子行程)→ 客戶管理員在「檢測基準」頁填的網址。那個網址可能是客戶自己的檔案伺服器、GitHub、或任何第三方
協定/埠 HTTPS(新登記只收 https://——白名單直接取 safe_http_fetch.ALLOWED_SCHEMES,不另立一份;http:// 回錯誤碼 DETECTION_TOOLS_400013)。既有的 http 基準不強制失效(避免客戶既有基準一次全滅),抽取時寫一筆醒目警告
傳什麼 規則包壓縮檔(InSpec profile:inspec.yml+Ruby 檢查腳本)。cinc-auditor 下載、解壓、載入——載入即執行,規則包裡的 Ruby 想做什麼就做什麼
怎麼驗身分 無。網址的伺服器不認 agent,agent 也不認伺服器(走 https 時由 cinc-auditor 的 HTTP 客戶端驗系統 CA;http 時全無)
完整性比對 雲端有做、agent 沒接。雲端第一次抽取成功時把下載到的壓縮檔 sha256 落庫(detection_tool_profile_versions.sha256),派工時 build_payload() 把 {uid, source_type: "url", url, sha256} 下發;agent 端 profile_cache.resolve_profile_source() 對 url 型「原樣回傳 URL 字串,不經 cache、不比對」——程式註解明寫「平台不經手檔案,交給 cinc-auditor 自己去取(現行為)」。所以雲端解析過的那份與 agent 實際跑的那份,沒有任何機制保證是同一份
跟 file 型的差別 file 型規則包經 C20 從雲端下載、sha256 對帳 required=True(缺指紋直接擋)、安全解壓到 cache;url 型全部跳過,由第三方工具直接抓
雲端那頭(C19)怎麼抓 safe_http_fetch.fetch_url_bytes:只收 https、解析後每一顆 IP 不得落私有/保留段(擋 RFC1918、loopback、雲端 metadata)、限 50MB、自己走重導向最多 3 跳(每跳重驗 IP)。這些保護只在雲端那一跳,agent 這一跳沒有
何時存在 客戶用網址(不是上傳檔)建了檢測基準,且派 CINC Auditor/GCB 掃描時

依據:套件 jedi_detection/app/service/detection_profile_service.py:959-962(只收 https)、jedi_detection/common/detection_profile_ref.py:43-73(build_payload url 型帶 sha256)、jedi_detection/common/safe_http_fetch.py(C19 的四道保護)、detection_profile_extraction_service.py:456-469(抽取時算 sha256);agent repo core/profile_cache.py:124-144(url 型原樣交出)、core/task_executor_connectors/inspec.py:855-884(_resolve_profile 交給 profile_cache 分流)。

§3

三、哪些功能會走這條線

群 功能 對威脅的意義
① 掃描時載入規則包 派 CINC Auditor/GCB 掃描、基準是 url 型 → 每台 agent 每次掃描都去抓一次 規則包決定「檢查什麼、怎麼判定合規」——換了規則包,掃描報告就是假的;規則包是 Ruby,換了規則包也能在 agent 容器裡跑任意程式(C23b T1)
② 雲端抽取(C19,不是本線) 建基準或更新來源時,雲端抓一次解析控制項清單給畫面看 這一跳有完整保護;問題是它保護的那份內容,agent 不一定拿到同一份
§4

四、這條線會帶來什麼威脅、駭客怎麼打

掃描在這條線上抓到 1 條問題(M03-5)。依這條線的特性再補兩種手法(T2、T3 無掃描實例,風險欄標明)。

# 風險 威脅 駭客怎麼打 得手什麼 STRIDE 實例
T1 🟡 中 在下載路徑上換掉規則包——不加密連線不用破解,加密連線也沒人比指紋 ① 客戶管理員用一個網址建了檢測基準(舊基準可能是 http);② 攻擊者站在代理程式下載的網路路徑上(同網段、DNS、代理伺服器);③ 代理程式領到掃描工作,cinc-auditor 去抓規則包時,攻擊者回一包換過的;④ 規則包裡的 Ruby 在 agent 容器(root)執行——讀憑證、開後門;同時用客戶主機帳密登進受檢主機跑假檢查,報告也一起造假;⑤ 若是 http,連破解都不用;若是 https,雲端下發的 sha256 agent 沒比,換了也不知道 在客戶內網的代理程式上執行任意程式碼,並偽造掃描結果 T 竄改資料、E 權限提升 M03-5 網址型規則包放行不加密連線、也不記指紋 🟡
T2 —(無掃描實例) 網址的主人事後換內容——雲端看到的是 A、agent 跑的是 B ① 攻擊者控制那個網址(自己架的、或攻下了客戶的檔案伺服器、或 GitHub 帳號被盜);② 建基準時放一份正常的規則包,讓雲端抽取、解析、算指紋、管理員在畫面上審過;③ 之後換成惡意版本;④ 每次派掃描 agent 都去抓最新的——拿到的是 B,但畫面上顯示的控制項清單還是 A 的;⑤ 不需要站在網路路徑上,不需要破解 TLS 同 T1,但攻擊者不必在內網 T 竄改資料、E 權限提升 —
T3 —(無掃描實例) 用規則包網址讓 agent 替人探內網、或抓巨檔撐爆 ① 有權建檢測基準的人填 https://10.0.0.5/x.tar.gz——雲端那跳擋內網 IP,抽取會失敗;但基準仍可建立(抽取失敗只是沒有控制項清單),派工時 url 照樣下發;② agent 的 cinc-auditor 從客戶內網去抓——這一跳沒有內網限制、沒有大小上限;③ 連得上/連不上從掃描失敗訊息看得出;或指向一個數 GB 的檔讓 agent 磁碟吃光 客戶內網探測;agent 停擺 I 資料外洩、D 讓服務停擺 —

三種手法的共同點:全部來自同一個結構性缺口——雲端審的那份與 agent 跑的那份是兩次獨立下載,中間沒有任何東西把它們釘在一起。sha256 已經算了也下發了,agent 端沒用上;C19 的四道保護(https、擋內網、限大小、限重導向)只保護雲端那一跳。這條線的本質風險不是「網址不安全」,是「同一個網址抓兩次,信任只建立在第一次」。

§5

五、我們要怎麼防、目前做到哪

對應三種威脅,防線分五條。D1、D2 直接對應掃描抓到的手法;標 ◇ 的是依這條線的特性補的,沒有實例。「目前」欄寫程式裡實際有的機制;⚠️ 表示沒有機制。

# 防線 擋哪種威脅 目前做到哪
D1 只收加密連線:新登記 https 限定;既有 http 基準要有退場(警告→期限→停用) T1 的「不用破解」那半 ✅ 新登記只收 https,白名單取自 safe_http_fetch.ALLOWED_SCHEMES 不另立;✅ 既有 http 抽取時寫醒目警告。⚠️ 既有 http 基準不強制失效、沒有退場期限——裁定避免客戶既有基準一次全滅,但也等於 http 這條路永遠開著
D2 agent 端比對雲端下發的指紋:url 型也走 agent 自己的下載器(而非交給 cinc-auditor)→ sha256 對帳 → 安全解壓 → 餵目錄給引擎,與 file 型同一條路 T1 的「沒人比指紋」那半、T2 全部 ⚠️ 沒有。雲端 build_payload() 已下發 sha256;agent profile_cache.resolve_profile_source() 對 url 型原樣回傳不比對。M03-5 的狀態欄明寫「代理端比對指紋屬後續小卡,本次未見對應 commit」——這就是那張小卡要做的事,兩頭差一步
D3 ◇ 內容漂移要可見:雲端定期(或每次派工前)重抓算 sha256,與落庫值不符就警告管理員「網址內容已變更,請重新審核」;派工時若不符則拒派 T2 ⚠️ 沒有。抽取是一次性的(建基準或手動重新解析);之後網址內容變了雲端不知道、畫面上的控制項清單是舊快照(程式註解明寫「url 型的清單是外部網址某一刻的快照,內容會漂」)
D4 ◇ agent 這一跳也要有 C19 那四道:擋內網 IP、限大小、限重導向、逾時——不信雲端一定擋過 T3 ⚠️ 沒有。cinc-auditor 自己抓,agent 管不到它的下載行為。做了 D2(改走 agent 下載器)這條就順帶有了——agent 的 _get_stream 已有大小上限與取消檢查,再加 IP 檢查即可
D5 ◇ url 型基準要過審才能派:抽取失敗(網址抓不到、不是合法規則包)的版本不得進入可派工狀態 T3 的「抽取失敗仍可建」那一步 ⚠️ 抽取失敗只影響控制項清單顯示,基準本身仍可建立並派工(build_payload 對 url 型只要 profile.url 有值就下發;sha256 可為 None,註解寫「屬已知缺口而非錯誤」)。沒查到「抽取成功才可發布」的狀態機約束

最該補的一步:D2,而且它已經在排程裡(M03-5 的後續小卡)。做法就是把 url 型從「原樣交出」改成「走 file 型同一條路」:agent 自己下載(順帶拿到 D4 的大小與 IP 限制)→ 比對下發的 sha256(T1、T2 一起擋掉)→ 解壓進 cache → 餵目錄給 cinc-auditor。profile_cache.py 的 file 型流程全部現成,差的是 url 型那個 return url 的分支改接過去。

§6

六、依這些防線,掃描還沒看過的地方

  • agent 端 url 型處理(D2、D4):掃描的 M03-5 是雲端套件那頭的條目,agent 端「原樣交出」這段沒有條目——它是 M03-5 打折的那一半。
  • 內容漂移偵測(D3):雲端完全沒有重抓機制,六頁零條。
  • url 型基準的狀態機(D5):抽取失敗能不能派,沒查到約束。
  • cinc-auditor 自己的下載行為:它用什麼 HTTP 客戶端、驗不驗憑證、有沒有大小上限——這是 Ruby 工具內部,沒查。做了 D2 這題就消失。
  • http 基準的退場(D1):有多少既有基準還是 http,沒查 DB。

依據:STRIDE 六頁信任邊界連線標記(CM-2403/2404 驗收後版本)、套件 jedi_detection/app/service/detection_profile_service.py/detection_profile_extraction_service.py/common/detection_profile_ref.py/common/safe_http_fetch.py、agent repo core/profile_cache.py/core/task_executor_connectors/inspec.py/core/task_executor.py、DFD Level 0 §2.3(C19)/§2.4(C24)。