弱點資料庫(Vulnerability Database)¶
功能群:系統管理|本頁服務的模組見 第三方元件風險 功能群總覽
事實基準:2026-10-11 從 FE
src/views/vulndb/VulndbManage.vue、src/composables/useVulndbUpload.js、BEapi/source_scan/routes/vulndb_route.py、app/source_scan_vulndb/service/vulndb_settings_app_service.py、core/plugins/_source_scan_vulndb*.py、jedi-source-scanapp/service/vulndb/、DEVpublic.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 |
- 計算指紋(畫面「計算更新包指紋中…」):瀏覽器算整包 SHA-256。這一步要求 https——瀏覽器只在安全連線提供這個功能,http 開啟會提示「瀏覽器需透過 https 連線才能計算更新包指紋」。
- 分塊上傳:每塊 50MB、每塊失敗重試 3 次;進度條。仍失敗提示「第 N 段上傳失敗(已重試),請檢查網路後重新上傳」。整包上限 1GB。
- 合併核對:後端合併後比對 SHA-256,不符 400
SOURCE_SCAN_400105;缺段 400SOURCE_SCAN_400104。 - 驗簽章並套用(畫面「驗證簽章並套用中,約需一兩分鐘…」):背景工作執行——驗原廠簽章、逐檔核指紋(失敗 400
SOURCE_SCAN_400101);日期沒有比現行新則拒絕(400SOURCE_SCAN_400102);通過後解到新日期目錄、切換現行指標、刪除舊目錄。 - 畫面輪詢背景工作,結束後顯示「弱點資料已更新為 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. 邊界情況與已知坑¶
- 沒有資料時掃描什麼都比不出來:沙箱唯讀掛同一個 volume,空的就掃不出任何弱點。安裝程式在沙箱啟動前先灌好。
- 升級不覆蓋較新的現場資料:客戶可能已從設定頁上傳過更新的一份,出貨包內的較舊就保留現場。
- 刪不掉舊目錄不算更新失敗:新資料已生效,記 log 等下次再清。
- http 開啟無法上傳:瀏覽器的指紋計算只在安全連線可用。
- SaaS 下租戶管理員看得到但不能改:
can_update=false。
13. 開發與驗證¶
- 導航:系統設定 → 弱點資料庫(
/system/vulndb) - DEV:資料在
~/.guidant-dev/vulndb(/opt/vulndb連結),開發鑰簽章;做法見docker/dev/README-source-scan.md - 驗收:上傳一份日期較新的簽章包 → 進度走完 → 日期與來源表更新、紀錄多一列「設定頁上傳 成功」;再傳同一份 → 「日期沒有比現行新」;未設更新站時「檢查更新」停用