内容
# Vulnify
一款 CVE 数据摄入和增强的流水线,构建一个单一的、标准化的 SQLite 数据库,从 CVEProject、NVD、CISA KEV、EPSS 和 OSV 中获取数据,并附带一个 Streamlit 资源管理器。
每次发布都附带一个已填充的 SQLite 数据库,因此您无需等待数小时即可完成初始数据摄入。
## 内容
- **完整的 CVE 语料库**,来自上游 CVEProject 的 `cvelistV5` zip 文件
- **NVD 批量合并**,用于 CVSS 指标、CPE 配置、漏洞状态和引用
- **CISA 已知漏洞**,包含 `date_added`、`due_date`、ransomware 标志和所需操作
- **EPSS** 利用概率 + 百分位,批量处理
- **OSV** 每个 CVE 的软件包映射
- **Streamlit 资源管理器**,具有约 70 个预建的数据视图
- **可恢复的流水线状态** — 中断后继续执行
当前快照(2026 年 5 月发布):
| | 数量 |
|--|--:|
| CVE | 347,248 |
| 厂商 | 21,183 |
| 产品 | 70,266 |
| KEV 条目 | 1,586 |
| 表 | 20 |
## 文档
更深入的参考资料位于 [`docs/`](docs/) 中:
- **[数据源](docs/DATASOURCES.md)** — 每个上游数据源、端点和许可证
- **[流水线](docs/PIPELINE.md)** — 数据摄入 → 增强,水位标记/恢复,cascade+heal 模型,三态规则
- **[模式](docs/SCHEMA.md)** — 20 表布局和查询注意事项
- **[MCP 服务器](docs/MCP.md)** — 7 种工具,每个代理设置,故障排除
- **[资源管理器](docs/EXPLORE.md)** — Streamlit 仪表板,选项卡
## 快速开始(使用预建的数据库)
如果您只想在不运行流水线的情况下查询数据:
```bash
# 1. 克隆并选择您需要的额外功能
git clone https://github.com/mez-0/vulnify.git
cd vulnify
uv sync --extra mcp # 用于代理 / MCP 服务器
# 或: uv sync --extra explore # 用于 Streamlit 仪表板
# 或: uv sync --all-extras # 用于所有功能
# 2. 获取最新的发布数据库
gh release download -R mez-0/vulnify --pattern vulnify.db.zst
zstd -d vulnify.db.zst -o vulnify.db
# 3. 将 .env 指向数据库
cat > .env <<EOF
VULNIFY_SQLITE_PATH=$(pwd)/vulnify.db
VULNIFY_SCHEMA_SQL_PATH=vulnify/db/schema.sql
EOF
# 4a. 从代理使用(完整设置请参见下面的“MCP 服务器”)
uv run vulnify-mcp </dev/null # 仅测试 — 应在 EOF 处启动然后退出
# 4b. 或在 Streamlit 资源管理器中浏览
uv run streamlit run explore/app.py
# 4c. 或直接查询 SQLite
sqlite3 vulnify.db "SELECT cve_id, summary FROM cve WHERE cve_id = 'CVE-2024-3094';"
```
## 从头开始构建数据库
```bash
uv sync
cp .env.example .env # 根据需要编辑路径
uv run vulnify-gather
```
首次运行需要 **数小时**,如果没有 NVD API 密钥(公共 NVD 速率限制约为每 30 秒 5 个请求)。使用密钥,速度大约快 10 倍。
在 <https://nvd.nist.gov/developers/request-an-api-key> 获取免费密钥,并在 `.env` 中设置 `VULNIFY_NVD_API_KEY`。
### 跳过阶段
`vulnify-gather` 公开标志,因此您可以重新运行个别增强阶段而无需重新摄入:
```bash
vulnify-gather --skip-ingestion # 不重新下载 CVEProject zip 文件
vulnify-gather --skip-nvd # 跳过 NVD 批量合并
vulnify-gather --skip-kev # 跳过 CISA KEV
vulnify-gather --skip-epss # 跳过 EPSS 批次
vulnify-gather --skip-osv # 跳过 OSV 每个 CVE 的查找
vulnify-gather --skip-nuclei # 跳过 Nuclei 利用模板摄入
vulnify-gather --skip-exploitdb # 跳过 Exploit-DB 工件摄入
vulnify-gather --skip-metasploit # 跳过 Metasploit 模块元数据摄入
```
流水线将阶段水位标记写入 `pipeline_run` 表,因此重新运行是幂等的 — NVD 仅获取自上一个水位标记以来的更改,KEV 重新同步整个目录,EPSS 仅更新过时的分数。
利用阶段(Nuclei / Exploit-DB / Metasploit)获取并缓存其语料库在 `~/.vulnify/cache` 下,并根据语料库版本(提交 SHA / 内容哈希)进行水位标记。当 cvelistV5 摄入运行时,摄入级联删除重新触摸的 CVE 的工件,因此在下一次运行时进行修复 — 否则自动跳过未移动的语料库。显式 `--skip-*` 始终获胜。三态 `exploit.public_poc` / `exploit.metasploit` 摘要布尔值从工件中实现:`null` 直到贡献源运行,然后 `true` / `false`。
## 配置
所有配置都位于项目根目录的 `.env` 中(由 `vulnify.settings` 加载)。
| 变量 | 必需 | 默认值 | 目的 |
|--|:-:|--|--|
| `VULNIFY_SQLITE_PATH` | 是 | `vulnify.db` | SQLite 数据库的位置。空/未设置将切换 CVEProject 摄入到仅打印模式。 |
| `VULNIFY_SCHEMA_SQL_PATH` | 是 | `vulnify/db/schema.sql` | 用于引导新数据库的 DDL。 |
| `VULNIFY_KEV_JSON_PATH` | 否 | `known_exploited_vulnerabilities.json` | CISA KEV 目录的本地副本。如果未设置且默认文件不存在,则提供者将获取它。 |
| `VULNIFY_NVD_API_KEY` | 否 | — | NVD API 密钥。没有它,您将受到速率限制,约为每 30 秒 5 个请求。 |
| `VULNIFY_CACHE_DIR` | 否 | `~/.vulnify/cache` | 利用语料库(Nuclei / Exploit-DB / Metasploit)的缓存位置。 |
相对路径相对于项目根目录解析。
## 架构
```
┌───────────────────┐
│ gather.py (CLI) │
└─────────┬─────────┘
│
▼
┌─────────────────────────────┐
│ providers/cveproject.py │ 批量下载 + 解析
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ db/sqlite_store.py │ 插入到规范化表中
└──────────────┬──────────────┘
│
▼
┌───────────────────┴────────────────────┐
│ providers/enrichment.py │
│ ├── cisa_kev (CISA KEV 目录) │
│ ├── nvd (CVSS, CPE, 状态) │
│ ├── epss (概率分数) │
│ ├── osv (软件包映射) │
│ └── exploit_ingest (Nuclei/EDB/MSF) │
└────────────────────┬───────────────────┘
│
▼
┌────────────────────┴────────────────────┐
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ explore/app.py (Streamlit) │ │ vulnify/mcp.py (FastMCP) │
└───────────────────────────────┘ └───────────────────────────────┘
```
### 源代码布局
```
vulnify/
├── vulnify/
│ ├── gather.py # `vulnify-gather` CLI(摄入 + 增强)
│ ├── mcp.py # `vulnify-mcp` FastMCP 服务器(stdio)
│ ├── settings.py # .env 加载器 + 路径解析器
│ ├── constants.py # 严重性、SourceTrust、ExploitMaturity 枚举
│ ├── cvss_severity.py # CVSS-base -> 严重性分桶
│ ├── http.py # 共享的 httpx 客户端 + 文件/zip 下载帮助器
│ ├── models/ # 数据类模型(CVE、Vendor、Product、CVSS、...)
│ ├── providers/
│ │ ├── cveproject.py # CVEProject 批量解析器
│ │ ├── nvd.py # NVD 2.0 API 客户端 + 每个 CVE 的合并
│ │ ├── cisa_kev.py # KEV 目录摄入
│ │ ├── epss.py # FIRST EPSS 批量增强
│ │ ├── osv.py # OSV 每个 CVE 的软件包查找
│ │ ├── exploit_ingest.py # Nuclei/Exploit-DB/Metasploit 工件摄入
│ │ ├── vendor_advisories.py
│ │ ├── enrichment.py # 阶段协调器
│ │ └── enrichment_resume.py
│ └── db/
│ ├── schema.sql # 20 表规范化模式 + FTS5 索引
│ ├── sqlite_store.py # 连接 + 插入 API
│ ├── readonly.py # 共享只读 sqlite3 帮助器
│ ├── cve_upsert.py # CVE/厂商/产品写入
│ ├── migrate.py # 幂等迁移 + FTS5 回填
│ ├── pipeline_state.py # 阶段水位标记
│ └── sql_conversion.py # 模型 <-> 行帮助器
├── explore/
│ ├── app.py # Streamlit 仪表板
│ ├── data.py # 概述查询
│ └── data_views.py # 每个图表查询
└── tests/ # pytest 套件(无网络,无真实数据库)
```
## 模式概述
20 张表,全部规范化,启用外键。顶级 CVE 加上单独的表用于高基数位(CPE 匹配、引用、CVSS 指标、利用信号 + 工件、KEV 列表、情报),以便您干净地连接。
```
cve — 主要 CVE 记录
vendor — 厂商(区分大小写/空格规范)
product — 厂商拥有的产品
cve_vendor — 具有 `角色` 的多对多关系(分配者、受影响者、来源等)
affected_product — CVE <-> 产品受影响/不受影响,并附有注释
version_range — 每个受影响产品的版本约束
cwe / cve_cwe — 弱点分类法
cvss — 任何来源的每个 CVSS 矢量,(源, 版本, 矢量) 去重
cpe_match — NVD 配置叶匹配
exploit — 利用可用性和成熟度(三态汇总布尔值)
exploit_artefact — 每个 CVE 的利用证据(Nuclei/Exploit-DB/Metasploit)
kev — 每个 CVE 的 CISA KEV 列表字段
intel — 通用威胁情报行(种类/值/来源)
intel_string_list — 情报行的后台列表值
reference — 带有信任 + 来源的 URL 引用
reference_tag — 引用标签的多对多关系
tag / cve_tag — CVE 级别的标签
pipeline_run — 每个阶段的水位标记,用于恢复
```
完整的 DDL 在 [`vulnify/db/schema.sql`](vulnify/db/schema.sql) 中;带有查询注意事项的注释演练在 [docs/SCHEMA.md](docs/SCHEMA.md) 中。
## MCP 服务器(`vulnify-mcp`)
`vulnify.mcp` 通过 [Model Context Protocol](https://modelcontextprotocol.io) 将 SQLite 数据库暴露给 AI 代理。它是一个 FastMCP 服务器,通过 stdio 讲话,因此像 Claude Code、Claude Desktop 和 Cursor 这样的代理根据需要将其作为子进程启动。
> 完整的工具参考、代理设置和故障排除: **[docs/MCP.md](docs/MCP.md)**。
### 步骤 1 — 设置项目
```bash
git clone https://github.com/mez-0/vulnify.git
cd vulnify
uv sync --extra mcp
```
### 步骤 2 — 获取 SQLite 数据库
两个选项:
**选项 A — 预建(推荐)**。下载发布资产并解压缩:
```bash
gh release download -R mez-0/vulnify --pattern vulnify.db.zst
zstd -d vulnify.db.zst -o vulnify.db
```
**选项 B — 从源代码构建**。需要数小时;请参见 [从头开始构建数据库](#从头开始构建数据库)。
### 步骤 3 — 将服务器指向数据库
在项目根目录下使用绝对路径创建 `.env`:
```bash
echo "VULNIFY_SQLITE_PATH=$(pwd)/vulnify.db" > .env
echo "VULNIFY_SCHEMA_SQL_PATH=vulnify/db/schema.sql" >> .env
```
### 步骤 4 — 烟雾测试
确认服务器启动并干净地关闭。它通过 stdio 讲话,因此只需发送 `Ctrl-D` (EOF)即可退出:
```bash
uv run vulnify-mcp </dev/null
```
如果您使用的发布数据库是在 FTS5 推出之前构建的,您将看到一次性约 8 秒的回填:
```
INFO 为 347248 个 CVE 行回填 FTS5 索引 — 一次性,耗时 ~30s
INFO FTS5 回填完成,耗时 8.5s
```
从 `v2026.05.21.1` 开始,发布版本已预建 FTS 索引,因此此步骤是静默的。
### 步骤 5 — 将其连接到您的代理
#### Claude Code
最简单的方法是使用 CLI:
```bash
claude mcp add vulnify \
--scope user \
-- uv run --directory "$(pwd)" vulnify-mcp
```
或直接编辑 `~/.claude.json`:
```json
{
"mcpServers": {
"vulnify": {
"command": "uv",
"args": ["run", "--directory", "/绝对路径/to/vulnify", "vulnify-mcp"]
}
}
}
```
验证它是否已连接:
```bash
claude mcp list
```
#### Claude Desktop
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或 `%APPDATA%\Claude\claude_desktop_config.json`(Windows):
```json
{
"mcpServers": {
"vulnify": {
"command": "uv",
"args": ["run", "--directory", "/绝对路径/to/vulnify", "vulnify-mcp"]
}
}
}
```
重启 Claude Desktop 后编辑。
#### Cursor
编辑 `~/.cursor/mcp.json`(或项目本地的 `.cursor/mcp.json`):
```json
{
"mcpServers": {
"vulnify": {
"command": "uv",
"args": ["run", "--directory", "/绝对路径/to/vulnify", "vulnify-mcp"]
}
}
}
```
### 代理可以调用的工具
| 工具 | 功能 |
|--|--|
| `get_cve(cve_id)` | 完整的 CVE 记录 — CVSS、KEV、EPSS、利用、引用、CWE、受影响的产品,加上一个 `artefacts` 证据列表。 |
| `search_cves(...)` | 按供应商/产品/CWE/KEV_仅/最小 CVSS/最小 EPSS/年份过滤。 |
| `exploits_for(cve_id)` | 具体的利用工件(Nuclei / Exploit-DB / Metasploit),带有来源、稳定 ID、URL 和 `exact` / `parsed` 置信度。 |
| `references_for(cve_id, tag)` | 引用 URL,带有它们的标签,可选过滤到一个标签(例如 `patch`、`exploit`)。 |
| `list_kev(since, limit)` | 最近的 CISA KEV 条目,按最新顺序排列。 |
| `database_overview()` | 总数、发布日期范围、最近的管道运行时间。 |
| `search_cves_text(query, limit)` | FTS5 文本搜索,支持 AND / OR / NOT / 引号短语 / `prefix*`。 |
所有工具都返回 JSON 可序列化的字典。限制在 100 行。
### 示例代理提示
- “CVE-2024-3094 是什么?”
- “显示我过去 60 天内 Cisco 添加的 KEV 条目。”
- “查找 CVSS ≥ 8 的 container escape 相关 CVE。”
- “哪些产品的 CVE 在 2025 年发布最多?”
### 故障排除
- **工具在已经运行的代理中不可用** — MCP 服务器在会话开始时附加,而不是在运行 `claude mcp add` 时。退出当前的 Claude Code / Cursor 会话并启动一个新的 — 不要 `/resume` 旧的。
- **`claude mcp list` 显示 `✗ 无法连接`** — 首先检查 `claude mcp get vulnify` 的确切 `Args:` 字段;常见的错误是复制粘贴截断,将 `vulnify-mcp` 变成 `vulnify-mc`。用 shell 原样测试生成的命令:`uv run --directory /path/to/vulnify vulnify-mcp </dev/null`。
- **`uv: command not found`** 在代理的进程中 — 代理继承了一个最小的 `PATH`。要么在配置中使用 `uv` 的绝对路径(`command: "/home/you/.cargo/bin/uv"`),要么将 `uv` 符号链接到 `/usr/local/bin`。
- **`VULNIFY_SQLITE_PATH` 在启动时未设置** — 您的 `.env` 文件未被拾取。服务器将 `.env` 解析为 vulnify 包根目录相对路径;传递一个绝对 `--directory` 到代理配置中,以便它位于正确的位置。
- **工具调用返回空值** — 使用 `uv run python -c "import sqlite3; print(sqlite3.connect('vulnify.db').execute('SELECT COUNT(*) FROM cve').fetchone())"` 确认数据库中有数据。
- **日志丢失** — `vulnify-mcp` 将日志记录到 stderr(以便它不会在 stdout 上损坏 MCP 协议)。大多数代理 UI 在其 MCP 日志视图中显示 stderr; 在 Claude Code 中,这是 `/mcp` 然后选择服务器。
## 资源管理器
`explore/app.py` 是一个 Streamlit 仪表板,包含大约 70 个预建的数据视图:严重性分布、KEV 列表延迟、EPSS 密度、CWE 共现热图、供应商/产品压力、CVSS 矢量分解、发布频率、利用中野生动物每月趋势等。
```bash
uv sync --extra explore
uv run streamlit run explore/app.py
```
视图分为 14 个选项卡(概览、供应商、趋势、供应商链接、严重性和 CWE、增强、利用景观、KEV 深入研究、CVSS 矢量、产品和 CPE、引用、威胁情报、生命周期、管道健康),并分布在两个查询模块中:`explore/data.py`(概览/着陆页)和 `explore/data_views.py`(每个图表的查询)。完整的选项卡到选项卡的分解以及如何添加视图: **[docs/EXPLORE.md](docs/EXPLORE.md)**。
## 测试
```bash
uv run pytest
```
测试是密封的 — 无网络,无真实数据库。它们涵盖:
- SQLite 存储插入/去重行为
- 模式迁移/回填
- NVD 批量合并
- 管道状态水位标记
- 增强恢复逻辑
- 资源管理器查询形状
- MCP 工具表面(结构化 + FTS5 搜索)
## 发布
每次发布都附带:
- **`vulnify.db.zst`** — 完整的 SQLite 数据库,zstd 压缩。从 `v2026.05.21.1` 开始预建 FTS5 索引,因此 `vulnify-mcp` 立即准备好服务。
- **`schema.sql`** — DDL,以防您只想要结构。
标签方案:
- **`vYYYY.MM.DD`** — 主要快照,该日期捕获数据。
- **`vYYYY.MM.DD.N`** — 数据快照的代码补丁(例如 `v2026.05.21.1` 是数据快照 `2026-05-21`,带有 `vulnify-mcp` 服务器)。
`pyproject.toml` 中的代码版本遵循 SemVer 独立。
## 许可证
在 [MIT 许可证](LICENSE) 下发布。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器