跳轉到

弱點資料庫(Vulnerability Database)

功能群:系統管理|本頁服務的模組見 第三方元件風險 功能群總覽

事實基準:2026-10-11 從 FE src/views/vulndb/VulndbManage.vue、src/composables/useVulndbUpload.js、BE api/source_scan/routes/vulndb_route.py、app/source_scan_vulndb/service/vulndb_settings_app_service.py、core/plugins/_source_scan_vulndb*.py、jedi-source-scan app/service/vulndb/、DEV public.vulndb_updates 實查掃出

變更紀錄

日期 FR 變更
2026-10-11 FR-134 新頁:第三方元件風險掃描用的弱點資料——查看資料日期與各來源、上傳更新包(分塊)、連網檢查更新、每日自動檢查、更新紀錄

1. 功能描述

第三方元件風險的掃描在沙箱裡離線比對弱點:沙箱不出網,所以弱點資料要事先放進機器裡。本頁管理這份資料——看現在是哪一天的、各來源各有多少筆、換新的一份、看歷次更新紀錄。

資料太舊會漏掉新公布的弱點,所以本頁與每次掃描的結果頁都會顯示資料日期並依年齡上色。

弱點資料是整台機器共用一份(/opt/vulndb),不是租戶資料:

  • 落地版一台一客戶,客戶管理員持 system.vulndb.update 即可更新。
  • SaaS 部署下,任一租戶都不准換掉全機共用的資料,寫入另要求平台管理員。

三種更新途徑,都走同一條套用流程(驗章 → 逐檔指紋 → 切換 → 寫更新紀錄):

途徑 誰觸發 紀錄的來源欄
安裝/升級 安裝程式從出貨包灌入;升級時包內資料比現場新才換 安裝/升級(installer)
設定頁上傳 管理員在本頁上傳更新包 設定頁上傳(ui_upload)
連網自動更新 管理員按「檢查更新」,或每日排程 連網自動更新(auto_download)

主要使用者:系統管理員。

角色速覽

角色 一句話
持 system.vulndb.update(落地版)/平台管理員(SaaS) 上傳、檢查更新、自動更新開關
只有 system.vulndb.read 看資料日期與紀錄;頁面提示「更新弱點資料需由系統管理員操作」

1.1 功能總覽

# 功能 說明 位置 詳述
1 目前弱點資料日期 日期 Tag(30 天內綠、超過 30 天黃、超過 90 天紅)+「距今 N 天」;超過 30 天多一段提醒 頁首 §5
2 資料來源表 Trivy 弱點資料庫、Grype 弱點資料庫、OSV 弱點資料庫、EPSS 被利用機率、CISA KEV 已遭利用清單:各自日期、版本或筆數 頁首下方 §5
3 上傳更新包 選 .zst 檔 → 計算指紋 → 分塊上傳 → 驗簽章並套用 頁首右 UC-VDB-01
4 檢查更新 向更新站查有無較新的一份,有就下載套用 頁首右 UC-VDB-02
5 每日自動檢查更新 開關;沒設定更新站時停用 頁面下方 UC-VDB-02
6 更新紀錄 時間、操作者、來源、資料日期(前 → 後)、結果 第二張卡 §5

2. Use Case

UC-VDB-01 上傳更新包

項目 內容
角色 可寫入者(見 §1)
前置條件 取得原廠簽章的更新包 guidant-vulndb-<日期>.tar.zst;瀏覽器以 https 開啟
產出 / 後置條件 資料切到新日期、舊目錄刪除;vulndb_updates 一列;稽核事件 6194

UC-VDB-01 上傳更新包

  1. 計算指紋(畫面「計算更新包指紋中…」):瀏覽器算整包 SHA-256。這一步要求 https——瀏覽器只在安全連線提供這個功能,http 開啟會提示「瀏覽器需透過 https 連線才能計算更新包指紋」。
  2. 分塊上傳:每塊 50MB、每塊失敗重試 3 次;進度條。仍失敗提示「第 N 段上傳失敗(已重試),請檢查網路後重新上傳」。整包上限 1GB。
  3. 合併核對:後端合併後比對 SHA-256,不符 400 SOURCE_SCAN_400105;缺段 400 SOURCE_SCAN_400104。
  4. 驗簽章並套用(畫面「驗證簽章並套用中,約需一兩分鐘…」):背景工作執行——驗原廠簽章、逐檔核指紋(失敗 400 SOURCE_SCAN_400101);日期沒有比現行新則拒絕(400 SOURCE_SCAN_400102);通過後解到新日期目錄、切換現行指標、刪除舊目錄。
  5. 畫面輪詢背景工作,結束後顯示「弱點資料已更新為 YYYY-MM-DD」或失敗原因,並重新載入本頁。

為什麼分塊:更新包約 480MB,一次上傳容易被反向代理或網路逾時打斷;分塊加重試讓中途斷線只需重傳那一塊。

為什麼日期不能倒退:防止把舊資料覆蓋回去(例如誤傳了較舊的包),讓掃描結果變得比實際乾淨。

UC-VDB-02 連網檢查更新與自動更新

項目 內容
角色 可寫入者(手動);系統(排程)
前置條件 部署設定 VULNDB_UPDATE_URL 已填(https)
產出 / 後置條件 有較新資料時同 UC-VDB-01 的套用結果;已是最新時不變
  • 更新站位址是部署設定、不是畫面欄位:VULNDB_UPDATE_URL,預設空。空的時候「檢查更新」與自動更新開關都停用,提示「未設定弱點資料更新站,無法連網更新;請改用『上傳更新包』」。封閉網路的客戶本來就留空。
  • 檢查流程(worker 內執行;沙箱照樣不出網):取 <URL>/latest.json({"bundle_date": "YYYYMMDD", "url": "...", "sha256": "..."},只收 https、不跟隨轉址)→ 不比現行新就回「目前已是最新資料(日期)」→ 較新則串流下載、邊下載邊算 SHA-256、與公布值比對 → 走 UC-VDB-01 第 4 步的同一條套用流程。
  • 連不上更新站、回應格式不對、下載中斷、SHA-256 不符,都不算程式錯誤:背景工作照樣完成,畫面顯示白話原因(例如「連不上弱點資料更新站,請確認網路或更新站位址」)。
  • 每日自動檢查:排程每天 04:10(UTC)跑一次;開關預設開(有填更新站的客戶本來就是要它自動更新),沒填更新站時排程看到空位址自己跳過。開關存在 ROOT 租戶的系統設定(VULNDB/auto_update_enabled);自動更新的紀錄操作者寫 system。

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
選單、進頁、看狀態與紀錄 ui_routes vulndb 綁 system.vulndb.read system.vulndb.read VulndbStatusRoute.get、VulndbJobRoute.get
上傳、檢查更新、自動更新開關 v-can=system.vulndb.update;且後端回 can_update=true 才顯示 system.vulndb.update;非落地版另要求平台管理員 VulndbUploadStartRoute/ChunkRoute/CompleteRoute、VulndbCheckUpdateRoute、VulndbAutoUpdateRoute;vulndb_settings_app_service.py::_assert_may_write
授權(license) — 不掛 require_license:基礎設施,不上報價單 vulndb_route.py
授權唯讀 useLicenseReadonly 停用寫入鈕 — VulndbManage.vue

出廠:migration 把兩顆 system.vulndb.* 發給既有租戶的 is_admin 角色。

can_update:狀態 API 回這個旗標,畫面據此決定顯不顯示寫入區。它是後端用同一道寫入檢查算出來的,不是另一套規則。

4. 狀態機與前置條件

條件 效果 出處
未設定更新站 「檢查更新」與自動更新開關停用;直接打 API 412 SOURCE_SCAN_412101 check_update
已有另一個更新在進行 409 SOURCE_SCAN_409101 vulndb_update_service.py::_exclusive
上傳工作階段不存在或過期 404 SOURCE_SCAN_404101 _source_scan_vulndb_upload.py
分塊編號或大小不合法 400 SOURCE_SCAN_400106 同上
自動更新開關存不進去 500 SOURCE_SCAN_500101 set_auto_update
背景工作查詢只認兩種單 別種背景工作的 uid 一律當查無(404) job_result
套用中途失敗 現行資料不動;新日期目錄殘留下次自動清 vulndb_update_service.py::_switch/_prune

5. UI 設計

弱點資料庫版面

  • 第一張卡:標題列右側「檢查更新」「上傳更新包」(只對可寫入者顯示);「目前弱點資料日期」+Tag+「距今 N 天」;超過 30 天的提醒「弱點資料超過 30 天黃色、超過 90 天紅色提醒。資料太舊會漏掉新公布的弱點,請上傳新的更新包或按『檢查更新』。」;資料來源表;上傳/套用進度;檢查結果訊息;自動更新開關。
  • 第二張卡「更新紀錄」:時間、操作者(暱稱)、來源、資料日期(前 → 後)、結果(成功/失敗)。

6. API 規格

守門:@jwt_required → @require_capability('system.vulndb.*'),不掛 license。

6.1 總清單

Method + Path 說明 能力點
GET /system/vulndb/status 現行日期、各來源、最近紀錄、更新站是否設定、自動更新開關、can_update read
POST /system/vulndb/uploads 開始分塊上傳,回 upload_id update
PUT /system/vulndb/uploads/{upload_id}/chunks/{index} 上傳一塊 update
POST /system/vulndb/uploads/{upload_id}/complete 合併核對、排套用工作,回 job_uid update
POST /system/vulndb/check-update 排檢查更新工作,回 job_uid update
PUT /system/vulndb/auto-update 自動更新開關 update
GET /system/vulndb/jobs/{job_uid} 輪詢套用/檢查工作結果 read

6.2 狀態回應(VulndbStatusSchema)

欄位 型別 說明
bundle_date date|null 現行資料日期;尚未安裝為 null
sources dict|null trivy/grype/osv/epss/kev 各自 updated_at、count 或版本
recent list 最近更新紀錄(VulndbUpdateRecordSchema:uid、bundle_date、previous_bundle_date、source、status、error、created_user、created_user_name、created_at)
update_site_configured bool
auto_update_enabled bool
can_update bool

6.3 寫入 request

端點 body
開始上傳 {"total_size": <1~1GB>, "total_chunks": <1~上限>}
完成上傳 {"sha256": "<64 位十六進位>"}
自動更新 {"enabled": true}

6.4 工作結果(VulndbJobResultSchema)

{"status": "...", "result": {...}, "error": "..."}。result.result 為 updated(帶 bundle_date)、up_to_date、failed(帶 error_code 或白話 error)。

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/vulndb/VulndbManage.vue 主頁
src/views/vulndb/VulndbUpdateHistory.vue 更新紀錄表
src/composables/useVulndbUpload.js 計算指紋、分塊上傳(50MB/塊、重試 3 次)、輪詢工作
src/service/VulndbService.js API 包裝
src/config/sourceScan.js 資料年齡上色門檻(30/90 天)
src/config/locales/i18n/{zh-tw,en}/vulndb.json 頁面字串

8. 後端檔案地圖

鏈路 檔案
Route api/source_scan/routes/vulndb_route.py
App service(寫入守門、自動更新開關) app/source_scan_vulndb/service/vulndb_settings_app_service.py
分塊上傳 core/plugins/_source_scan_vulndb_upload.py
套用工作 core/plugins/_source_scan_vulndb.py → jedi-source-scan app/service/vulndb/vulndb_update_service.py::apply(驗章、逐檔指紋、切換、留紀錄)
連網更新 core/plugins/_source_scan_vulndb_fetch.py(latest.json、串流下載、排程入列)
排程 core/scheduler.py(vulndb_auto_update,每日 04:10 UTC)
安裝/升級灌入 scripts/installer/vulndb.sh → BE image RUN_MODE=vulndb-import(與設定頁同一支 apply())
更新包製作 scripts/build/(原廠端,見該目錄 README)

9. DB

9.1 public.vulndb_updates

欄位 型別 說明
id / uid bigint / uuid NOT NULL
bundle_date date 更新包資料日期;包解不開或驗章失敗時為空
previous_bundle_date date 套用前的現行資料日期;首次匯入為空
source varchar(16) NOT NULL installer(裝機/升級)|ui_upload(設定頁上傳)|auto_download(連網自動)
status varchar(16) NOT NULL succeeded|failed
error text
sha256 char(64) 整包壓縮檔的 SHA-256
sources jsonb 包內各來源資料日期、版本、筆數
created_user varchar(100) 操作者 login_name;安裝程式與自動更新寫 system
created_at timestamptz NOT NULL

全機共用、沒有 tenant_id。自動更新開關存在 public.system_configs(ROOT 租戶,VULNDB/auto_update_enabled)。

10. 頁面邏輯與資料對應

  • 載入:GET /status;can_update=false 時寫入區整塊不顯示、改顯示唯讀提示。
  • 資料年齡:以「今天 − bundle_date」算(結果頁則以掃描完成時間算,見掃描結果頁)。
  • 上傳與檢查更新都回 job_uid,前端輪詢 GET /jobs/{job_uid} 直到結束,再重新載入狀態。

11. 背景行為與外部依賴

類型 內容
背景工作 套用(vulndb_apply)、檢查更新(vulndb_check_update,max_attempts=1);都在 worker 跑
排程 每日 04:10 UTC;未設更新站或開關關閉時不入列
對外連線 只有「檢查更新」會連 VULNDB_UPDATE_URL(https);沙箱與 api 都不連
磁碟 解開約 4.7GB;更新時新舊兩份並存約 9.5GB;壓縮包約 480MB。切換完成後舊的自動刪除
稽核事件 6194 VULNDB_UPDATE
系統參數 VULNDB_UPDATE_URL(選填,預設空)

12. 邊界情況與已知坑

  1. 沒有資料時掃描什麼都比不出來:沙箱唯讀掛同一個 volume,空的就掃不出任何弱點。安裝程式在沙箱啟動前先灌好。
  2. 升級不覆蓋較新的現場資料:客戶可能已從設定頁上傳過更新的一份,出貨包內的較舊就保留現場。
  3. 刪不掉舊目錄不算更新失敗:新資料已生效,記 log 等下次再清。
  4. http 開啟無法上傳:瀏覽器的指紋計算只在安全連線可用。
  5. SaaS 下租戶管理員看得到但不能改:can_update=false。

13. 開發與驗證

  • 導航:系統設定 → 弱點資料庫(/system/vulndb)
  • DEV:資料在 ~/.guidant-dev/vulndb(/opt/vulndb 連結),開發鑰簽章;做法見 docker/dev/README-source-scan.md
  • 驗收:上傳一份日期較新的簽章包 → 進度走完 → 日期與來源表更新、紀錄多一列「設定頁上傳 成功」;再傳同一份 → 「日期沒有比現行新」;未設更新站時「檢查更新」停用