---
title: C23a agent → 客戶自架工具伺服器
eyebrow: Guidant AI 資安檢視總報告 · 連線清單
h1: C23a 代理程式 → 客戶自架的工具伺服器（OpenVAS／ZAP／SonarQube）
lede: 代理程式連客戶自己架的掃描工具伺服器——叫 OpenVAS 建掃描、叫 ZAP 掃網站、把 sonar-scanner 的結果推給 SonarQube。位址與帳密全是客戶在設定頁填的。掃描六頁沒有一條落在這條線上；但它連的是**客戶內網裡權限最高的幾台機器之一**（弱點掃描器知道全網的洞）。這一頁回答：這條線**怎麼連**、**哪些功能走它**、依特性**可能有什麼威脅**、我們**要怎麼防、目前做到哪**。
chips:
  - { text: "依設定", kind: plain }
  - { text: "位址客戶填・多半不驗憑證", kind: warn }
  - { text: "可能手法 3 種", kind: accent }
  - { text: "掃描命中 0 條", kind: plain }
---

> **這一頁怎麼來的**：[DFD Level 0](../DFD/dfd-level0.html#c23a) 把產品運作時的連線編成 C01～C25；[STRIDE 六頁](../STRIDE/S-spoofing.html)每一條問題都標了發生在哪幾條線。**這條線零命中**——agent 的 connector 層不在掃描範圍。第四段寫的是依這條線的特性可能的手法，沒有掃描實例。

## 一、連線圖

```{.mermaid cap="C23a — agent 連三種客戶自架的工具伺服器。三條都是客戶填位址、帳密由雲端加密存、派工時下發。紅色：OpenVAS 的 TLS 不驗憑證、ZAP 與 SonarQube 位址沒寫 scheme 時補 http——三條預設都沒有辨認「對方是不是真的那台伺服器」的機制。"}
%%{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
    API["guidant-api<br/>派工時解密工具帳密"]
    subgraph AGENTBOX["🏢 客戶機房"]
        direction LR
        AG["evidence-agent<br/>connector：openvas／zap／sonarqube"]
        OV(["OpenVAS／GVM<br/>GMP over TLS :9390<br/>（不驗憑證）"])
        ZAP(["ZAP daemon<br/>HTTP API :8080<br/>（當 proxy・API key）"])
        SQ(["SonarQube Server<br/>HTTP(S) · Bearer token"])
        MITM(["🕵 同網段的人<br/>假冒工具伺服器"])
        AG == "GMP · 帳密" ==> OV
        AG == "HTTP · API key<br/>目標網址由任務指定" ==> ZAP
        AG == "HTTPS/HTTP · token<br/>sonar-scanner 推結果" ==> SQ
        MITM -. "回應 TLS 握手或攔明文" .-> AG
    end
    API -- "C20 · 心跳回應帶明文帳密" --> AG
    classDef ext fill:#FBFCFC,stroke:#9AA8AA,stroke-dasharray:3 2
    classDef open fill:#FDECEC,stroke:#C0392B
    class OV,ZAP,SQ,MITM ext
    class MITM open
```

## 二、這條線怎麼連

| 項目 | 現況 |
|---|---|
| **誰 → 誰** | 客戶機房的 `evidence-agent` → 客戶自己架的工具伺服器。三種工具三條子線，都在客戶內網；雲端連不到也不碰 |
| **OpenVAS** | **GMP over TLS :9390**，用 python-gvm 的 `TLSConnection`。**不帶憑證時 python-gvm 預設 `verify_mode = CERT_NONE`、`check_hostname = False`**——有加密、但不驗對方是誰。帳密是 OpenVAS 管理員帳號（`username`／`password`）。位址填 `base_url`，程式只取 hostname |
| **ZAP** | **HTTP API :8080**（ZAPv2），ZAP 當 proxy 用——agent 所有 API 呼叫經 proxy 轉；位址無 scheme 時補 `http://`。帳密是 ZAP 的 API key。**要掃的目標網址**（`target_url`）由任務參數指定 |
| **SonarQube** | agent 本機跑 `sonar-scanner` 後**推結果到** SonarQube Server（Server 沒有觸發掃描的 API）；另有 HTTP 呼叫查專案狀態、拉快照。`httpx.get` 用預設設定（有 TLS 就驗系統 CA）；位址無 scheme 時補 `http://`。帳密是 user token（`squ_` 前綴），走 `Authorization: Bearer`、scanner 走環境變數 `SONAR_TOKEN` 不進命令列 |
| **怎麼驗身分** | **agent 對伺服器**：客戶填的帳密／API key／token，雲端加密存 `tenant_detection_tool_configs`、派工時解密經 [C20](C20-agent-to-frontdoor.html) 下發，agent 只在記憶體用、log 不記。**伺服器對 agent**：OpenVAS 不驗憑證；ZAP、SonarQube 明文 http 時無從驗，https 時 SonarQube 驗系統 CA |
| **位址誰填** | 客戶管理員在「檢測工具設定」頁填。雲端側對位址**沒有內網／外網限制**（DFD 寫「總表 #4／#79 已擋內網」——#4 是加權限門、#79 是限量＋收斂回應，**都不是擋內網位址**；位址仍由客戶自由填，已回寫母卡） |
| **何時存在** | 客戶設了對應工具且派該工具的掃描時 |

依據：agent repo `core/task_executor_connectors/openvas.py:59-85`（`TLSConnection(hostname, port, timeout)` 不帶 cafile）、python-gvm `gvm/connections/_tls.py:80-84`（無憑證時 `CERT_NONE`）、`zap.py:131-160`（`http://` 補 scheme、proxies 設定）、`sonarqube.py:319-354`／`1024-1049`（httpx 預設、`SONAR_TOKEN` 環境變數）；套件 `jedi_detection/app/service/detection_tool_service.py:35-36,238`（限量不限位址）。

## 三、哪些功能會走這條線

| 群 | 功能 | 對威脅的意義 |
|---|---|---|
| **① 建掃描、拉報告** | OpenVAS：建 target、建 task、等完成、拉 PDF 報告；ZAP：建 context、跑 spider 與 active scan、拉 HTML 報告 | agent 以管理員身分操作工具——工具伺服器**知道全網的弱點**，它的帳密比一般主機帳密更值錢 |
| **② 推源碼分析結果** | SonarQube：`sonar-scanner` 分析完 agent 本機的源碼（[C23b](C23b-agent-local-processes.html)）後推到 Server；Server 不存在的專案會**自動建立**（寫入） | 推的內容是客戶源碼的分析結果（檔名、問題行號、程式片段）——走明文就是源碼結構外流 |
| **③ 測試連線** | 「測試連線」對工具伺服器驗一次帳密（OpenVAS `authenticate`、ZAP 問版本、SonarQube `api/authentication/validate`） | 位址由按的人填（[C21](C21-api-to-agent-dataplane.html) T3）；帳密會被送到那個位址 |

## 四、依這條線的特性可能的攻擊手法（無掃描實例）

這條線零命中。依特性——**位址客戶填、帳密是工具管理員級、三條子線預設都不驗對方身分**——可能的手法有三種。風險欄寫「—（無掃描實例）」。

| # | 風險 | 威脅 | 駭客怎麼打 | 得手什麼 | STRIDE | 實例 |
|---|---|---|---|---|---|---|
| T1 | —（無掃描實例） | **假冒工具伺服器，接走管理員帳密** | ① 站在 agent 與工具伺服器之間（同網段、改 DNS、或工具伺服器的 IP 被重新分配）；② 架一個假的 :9390 回應 TLS 握手——agent 的 python-gvm 不驗憑證，直接接受；③ agent 送 GMP `authenticate`，OpenVAS 管理員帳密到手；④ ZAP／SonarQube 若是明文 http，連握手都不用，攔下來就讀 | 弱點掃描器的管理員帳密——登進去能看客戶全網的弱點報告、改掃描設定 | [S 冒充身分](../STRIDE/S-spoofing.html)、[I 資料外洩](../STRIDE/I-information-disclosure.html) | — |
| T2 | —（無掃描實例） | **假冒工具伺服器，回假報告** | ① 同 T1 的位置；② 不只接帳密，還照 GMP／ZAP API 格式回「掃描完成、零弱點」與一份乾淨的 PDF／HTML；③ agent 當真報告上傳，進入證據鏈；④ 稽核人員看到的是假的乾淨報告 | 偽造弱點掃描的稽核證據 | [T 竄改資料](../STRIDE/T-tampering.html) | — |
| T3 | —（無掃描實例） | **把 agent 當跳板，叫工具去打不該打的地方** | ① 有權設定任務的人（或 [C02](C02-frontdoor-to-api.html) 守門漏掉時任何人）；② ZAP 任務的 `target_url` 填客戶內網另一套系統、或填外部第三方網站；③ agent 叫 ZAP 對它跑 active scan——那是真實的攻擊流量（注入測試、暴力路徑）；④ 被掃的系統若脆弱會真的受損；若是外部網站，客戶變成攻擊來源 | 對內網或外部目標發動實質攻擊流量；客戶 IP 被列黑名單 | [E 權限提升](../STRIDE/E-elevation-of-privilege.html)、[D 讓服務停擺](../STRIDE/D-denial-of-service.html) | — |

**三種手法的共同點**：T1、T2 都利用「**agent 不確認對方是不是真的那台工具伺服器**」——這和 [C23](C23-agent-to-target-host.html) 的 SSH 不驗指紋是同一種病，只是這裡的帳密是弱點掃描器的管理員。T3 利用「**掃描目標由使用者填，而掃描本身就是攻擊**」——這是 DAST 工具的本質，產品能做的是確認填目標的人有權、並留下紀錄。

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

零命中的線沒有「直接對應掃描手法」的防線，**五條全部是依連線特性補的標準防線，全標 ◇**。「目前」欄寫程式裡實際有的機制；⚠️ 表示沒有機制。

| # | 防線 | 擋哪種威脅 | 目前做到哪 |
|---|---|---|---|
| D1 ◇ | **OpenVAS 的 TLS 要驗憑證**：讓客戶在設定頁上傳 OpenVAS 伺服器憑證或 CA，agent 用它驗；或至少釘指紋 | T1、T2 | ⚠️ **沒有**。`TLSConnection(hostname, port, timeout)` 不帶 `cafile`，python-gvm 退回 `CERT_NONE`。設定頁沒有憑證欄位 |
| D2 ◇ | **ZAP／SonarQube 預設走 https、明文要明示**；SonarQube 的 https 驗系統 CA（已有）或客戶上傳的 CA | T1、T2 | ⚠️ 兩者位址無 scheme 時都補 `http://`——預設是明文那一邊。SonarQube 填 `https://` 時 httpx 會驗系統 CA（內網自簽會失敗、沒有「上傳 CA」選項，實務上客戶會退回 http）。ZAP daemon 本身多半只開 http，這條有實務理由，但至少畫面要警告 |
| D3 ◇ | **工具帳密不落地、不進命令列、不進日誌** | T1 的暴露面 | ✅ 三支 connector 都只在記憶體用、log 不記帳密；✅ SonarQube token 走環境變數 `SONAR_TOKEN` 不進 argv；✅ 設定頁回應遮密鑰（雲端側） |
| D4 ◇ | **誰能設定掃描目標要守住，且目標要留紀錄**：ZAP 的 `target_url`、OpenVAS 的 `hosts` 都是攻擊目標，誰填的、填了什麼要進稽核日誌 | T3 | ✅ 派工只放行被指派人與 manager（[C02](C02-frontdoor-to-api.html) D1）；✅ 掃描目標數上限 256（`DETECTION_SCAN_TARGET_MAX_HOSTS`）。⚠️ **刻意不設目標白名單**（裁定：哪台算合法由客戶管）；掃描目標有沒有逐筆進稽核日誌沒查 |
| D5 ◇ | **從工具伺服器拉回的報告是外部輸入**：大小上限、格式驗證、進證據前消毒 | T2 的後果縮小 | ✅ 報告檔名進雲端前過 `sanitize_report_filename()`（[C20](C20-agent-to-frontdoor.html) D3）；✅ 預覽端白名單＋驗檔頭（[C01](C01-browser-to-frontdoor.html) D4）。⚠️ 報告**內容**真偽無法技術驗證——假報告長得跟真的一樣 |

**最該補的一步**：D1。OpenVAS 是三者中帳密最值錢的（弱點掃描器管理員＝全網弱點地圖），而它的 TLS 連線目前等於沒有 TLS——設定頁加一個「伺服器憑證／CA」上傳欄位、`TLSConnection` 帶 `cafile`，是一支 connector 幾行的事。

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

- **三支 connector 整個不在掃描範圍**：連線方式、憑證驗證、回應解析——六頁 STRIDE 零條。
- **OpenVAS `CERT_NONE`**（D1）：是第三方套件的預設行為，不是我們寫的——但我們沒覆寫。
- **ZAP／SonarQube 明文預設**（D2）：畫面有沒有警告沒看 FE。
- **掃描目標的稽核日誌**（D4）：測試連線有記（M03-6 修的），正式派工的目標清單有沒有記沒查。
- **DFD 的「已擋內網」說法**：§2.4 C23a 寫「位址客戶自填（總表 #4／#79 已擋內網）」——實查兩條都不是擋位址，已回寫母卡請首腦裁。

---

*依據：agent repo `core/task_executor_connectors/openvas.py`／`zap.py`／`sonarqube.py`、python-gvm `gvm/connections/_tls.py`、套件 `jedi_detection/app/service/detection_tool_service.py`、主專案 `config/config.py`、DFD Level 0 §2.4／§2.6。*
