Skip to content

扫描与监控

扫描是 CVE Intelligence Panel 的核心循环。本章对比 完整扫描监控,说明服务端行为,并为运维提供示意图。

为何有两种模式

NVD 覆盖广但实施 速率限制。每两分钟轮询 NVD 会卡顿或失败。因此 监控 跳过 NVD、查询更快源。完整扫描 用于可接受延迟时的全量清单。

运维通常每日(或按需)完整扫描一次,其间保持监控开启。

模式对比

方面 完整扫描 监控
端点 POST /api/scan POST /api/watch
NVD
KEV 预取 是(用于标记)
客户端 knownIds 非必需 去重「新」发现
meta.mode full watch

完整扫描流程

flowchart LR
  classDef ui fill:#e9edf5,stroke:#00baba,color:#253343
  classDef api fill:#f3fcfc,stroke:#008c8c,color:#253343
  classDef ext fill:#fff7ed,stroke:#eda232,color:#253343

  UI[浏览器]:::ui --> S[POST /api/scan]:::api
  S --> KEV[加载 KEV 集合]:::api
  S --> GH[GitHub 缓存]:::api
  S --> RSS[RSS 源]:::api
  S --> Loop[按栈工具]:::api
  Loop --> NVD[NVD 查询]:::ext
  Loop --> OSV[OSV 查询]:::ext
  Loop --> GHA[GitHub advisories]:::ext
  S --> M[合并 + KEV  enrichment]:::api
  M --> T[可选翻译]:::api
  T --> R[JSON 响应]:::api

图解说明

服务端一次性加载共享目录,再对每个工具并行查询 NVD(完整模式)、OSV 与 GitHub,并附加 RSS 关键词匹配。结果按 CVE id 合并;KEV 成员设置 exploited_in_wild。可选翻译填充 translations / title_fameta.sources_updated_at 记录各源成功拉取时间。

完整扫描步骤

  1. 用户点击 完整扫描;客户端发送 stacktranslate 标志。
  2. 服务端校验栈数组并启动计时。
  3. 并行加载 CISA KEV JSON、GitHub advisory 页(缓存)与 RSS。
  4. 对每个工具在 SCAN_DAYS 窗口内查询 NVD/OSV/GitHub。
  5. mergeVulnerabilities 去重并合并 sources 标签。
  6. enrichWithKev 标记已被利用的 CVE。
  7. translate: true,扫描时可能填充波斯语字段;其他语言稍后通过 /api/translate 请求。
  8. 返回汇总计数与 vuln 数组;客户端经 src/lib/scanCache.ts 持久化(stackKey 须与当前栈一致)。

客户端扫描缓存

浏览器在 cve-radar:last-scan 中保存上次成功扫描,附带 栈键(规范化、排序后的工具名)。重载时,loadLastScan 在键匹配时恢复 vuln 与 summary;否则忽略缓存。persistLastScan 在完整扫描后及 watch 返回新项时运行。

这样可避免每次浏览器会话都强制完整扫描,同时将结果限定于当前栈。

监控时序

sequenceDiagram
  participant B as 浏览器
  participant A as Express API
  participant O as OSV
  participant G as GitHub
  participant R as RSS

  B->>A: POST /api/watch {stack, knownIds}
  A->>O: 按工具查询
  A->>G: Advisory 缓存
  A->>R: 解析 feed
  A->>A: 合并并与 knownIds  diff
  A-->>B: newVulns, hasNew, meta

监控步骤

  1. useWatch 钩子按设置间隔(2/5/15 分钟)触发。
  2. 客户端将当前 CVE id 作为 knownIds 发送。
  3. 服务端仅拉取 OSV/GitHub/RSS。
  4. 不在 knownIds 中的新 id 填入 newVulns;启用告警时显示横幅/toast。
  5. 客户端合并本地 vuln 列表并更新 sources_updated_at

GitLab 与 Linux 发行版数据源

除 NVD/OSV/GitHub/RSS 外,完整扫描可在源设置或环境变量中启用 GitLab Advisory Database(GraphQL)及多个 Linux 发行版安全数据源

作用
GitLab 包级公告(npm、PyPI、Maven、Go 等)— AIRGAPPED=true 时除非设置 GITLAB_ADVISORY_MIRROR_URL 否则跳过
Alpine 各 release 的 secdb JSON(ALPINE_RELEASES
Ubuntu USN 从 Ubuntu 安全 JSON 预取的 CVE→包映射
Red Hat enrichment(CVE 元数据,非独立行)
Debian Security Tracker(DEBIAN_ENABLED 或 air-gap 的 DEBIAN_TRACKER_CACHE_PATH
Amazon Linux ALAS updateinfo XML
MITRE CVE 可选 JSON 5.x enrichment(MITRE_CVE_ENABLED=true

包级匹配见 shared/distroPackages.ts(栈工具 → 发行版包名)。发行版结果按 CVE id 与 NVD/OSV 去重;sources_failed 与其他内置源一样记录部分失败。

说明与例外

  • 服务端速率限制(429): POST /scanPOST /watch 使用独立的每 IP 内存桶(RATE_LIMIT_SCAN_PER_MIN 默认 12,RATE_LIMIT_WATCH_PER_MIN 默认 120)。响应:code: "RATE_LIMITED"retryAfterSecPOST /scan/validate 不限速。开发中多标签页或 React StrictMode 可能触发 watch 限制 — 关闭多余标签或调整 env。
  • NVD_API_KEY 时,大栈可能收到 NVD upstream 的 HTTP 403/429 — 稍后重试或添加密钥(与应用速率限制不同)。
  • 设置中可选每 30 分钟 自动完整扫描;与监控间隔独立。
  • 顶栏扫描进度条在长扫描期间反映客户端进度估算。

下一章:国际化与翻译