jcastanedacano/cve-sentry
GitHub: jcastanedacano/cve-sentry
一个面向 Azure 与 Microsoft 365 的威胁情报平台,自动化聚合与关联多源 CVE 数据并提供可视化与工作流管理。
Stars: 1 | Forks: 0
# CVE Sentry
**Azure 与 Microsoft 365 的威胁情报平台**
CVE Sentry 是一个自动化的威胁情报管道,用于收集、关联并可视化来自 13 个安全来源的 CVE 数据。它结合了 Python 异步后端与 Next.js 仪表板,专注于 Azure 和 Microsoft 365 环境。
在线实例:[sentry.d3fend.me](https://sentry.d3fend.me)
## 包含内容
- **每日仪表板与优先级排序**(立即处理 / 本周关注 / 监控),由 Sentry 优先级评分(0-10)驱动,结合 CVSS、EPSS、KEV 状态、可利用性以及时效性。
- **每个漏洞的清晰信号**:每个威胁均显示 CISA KEV 徽章与可利用性指示器,让您即时了解野外正在被积极利用的内容。
- **带有分析功能的威胁脉冲**:随时间变化的趋势、暴露最多的产品(前 5 名)、严重性分布图表、MITRE ATT&CK 战术热力图,以及支持按日细分的交互式时间线日历。
- **观察列表**:用于监控特定供应商、产品或关键词。可按最低严重性过滤并启用仅 KEV 模式,获取与您的环境最相关的内容。
- **工作流看板**:包含 5 个状态(新建 → 分类 → 缓解中 → 已修复 → 忽略),支持拖放卡片并将工单导出至 Jira、ServiceNow、GitHub Issues 或自定义系统。
- **MITRE D3FEND 的防御措施**:每项威胁均映射到可操作的缓解措施,分为加固、检测、隔离、欺骗或清除,将威胁情报转化为即时行动步骤。
## 架构
```
13 Security Sources (async/parallel)
MSRC | NVD | CISA KEV | GitHub | Sentinel
Exploit-DB | ZDI | CERT-EU | EPSS | ...
|
v
+-------------------------------+
| Python Pipeline (async) |
| Correlation | MITRE ATT&CK |
| D3FEND | Risk Scoring | LLM |
+-------------------------------+
|
dashboard_data.json
|
v
+-------------------------------+
| Next.js 16 Dashboard |
| Auth (Entra ID/GitHub/Google) |
| Real-time threat visualization|
+-------------------------------+
|
v
Azure App Service (Docker)
```
## 功能特性
- **并行收集的 13 个威胁来源**(MSRC、NVD、CISA KEV、GitHub Advisories、Exploit-DB、ZDI、CERT-EU、Microsoft Sentinel、MS Defender 博客、MS Tech Community、MSRC CVRF、EPSS)
- **MITRE ATT&CK 映射**:带战术热力图可视化
- **D3FEND 缓解措施**:用于防御建议
- **Sentry 优先级评分**(0-10):具备可解释性因素
- **产品过滤**:针对 Azure/M365(91 个产品关键词)
- **增量检测**:突出显示自上次运行以来的新 KEV 与可利用项
- **LLM 摘要**:通过 OpenAI 或 Anthropic 提供(可选,备有模板回退)
- **身份验证**:支持 Microsoft Entra ID、GitHub 与 Google OAuth
- **工作流管理**:包含事件跟踪与工单导出
- **观察列表**:用于自定义威胁监控
- **数据导入/导出与跨实例同步**
- **90 天自动保留**:支持可配置的清除策略
- **RSS 订阅**:用于威胁更新
## 技术栈
| 组件 | 技术 | 版本 |
|-----------|-----------|---------|
| 前端 | Next.js(应用路由) | 16.1.6 |
| UI | React + TypeScript | 19.2.3 |
| 样式 | Tailwind CSS + Radix UI | 4.x |
| 认证 | Auth.js(NextAuth v5) | 5.0-beta |
| 后端 | Python(异步) | 3.13 |
| HTTP | aiohttp | 3.9+ |
| 调度 | APScheduler | 3.10+ |
| 威胁数据 | MITRE ATT&CK + STIX2 | 3.0+ |
| 部署 | Docker + Azure 应用服务 | - |
| CI/CD | GitHub Actions | - |
| 注册表 | Azure 容器注册表 | - |
## 快速启动(本地开发)
### 前置条件
- Python 3.13+
- Node.js 22+
- npm 10+
### 1. 克隆仓库
```
git clone https://github.com/jcastanedacano/cve-sentry.git
cd cve-sentry
```
### 2. 设置 Python 管道
```
cd cve_sentry
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux/Mac
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
```
编辑 `.env` 文件以配置您的设置(所有项均为可选基础运行配置):
```
LLM_PROVIDER= # "openai" or "anthropic" (leave empty for template summaries)
OPENAI_API_KEY= # Required if LLM_PROVIDER=openai
ANTHROPIC_API_KEY= # Required if LLM_PROVIDER=anthropic
GITHUB_TOKEN= # Optional: higher GitHub API rate limits
DAYS_LOOKBACK=7 # Days of CVE history to collect
RETENTION_DAYS=90 # Auto-purge threshold
PRODUCT_FILTER_ENABLED=true # Filter for Azure/M365 only
```
### 3. 运行管道
```
# 单次运行(推荐首次使用)
python main.py --now
# 计划模式(每 4 小时运行一次)
python main.py
```
此步骤将生成 `output/dashboard_data.json`,仪表板会读取该文件。
### 4. 设置 Next.js 仪表板
```
cd ../sentry
npm install
```
### 5. 配置身份验证
创建 `sentry/.env.local` 文件:
```
AUTH_SECRET=your-random-secret-here # Generate: npx auth secret
# Microsoft Entra ID
AUTH_MICROSOFT_ENTRA_ID_ID=your-client-id
AUTH_MICROSOFT_ENTRA_ID_SECRET=your-client-secret
AUTH_MICROSOFT_ENTRA_ID_ISSUER=https://login.microsoftonline.com/your-tenant-id/v2.0
# GitHub OAuth
AUTH_GITHUB_ID=your-github-client-id
AUTH_GITHUB_SECRET=your-github-client-secret
# Google OAuth
AUTH_GOOGLE_ID=your-google-client-id
AUTH_GOOGLE_SECRET=your-google-client-secret
```
**OAuth 回调 URL(用于提供程序注册):**
| 提供程序 | 回调 URL |
|----------|-------------|
| Microsoft Entra ID | `http://localhost:4000/api/auth/callback/microsoft-entra-id` |
| GitHub | `http://localhost:4000/api/auth/callback/github` |
| Google | `http://localhost:4000/api/auth/callback/google` |
### 6. 启动仪表板
```
npm run dev
```
打开 [http://localhost:4000](http://localhost:4000)
## Docker 部署
### 本地构建与运行
```
docker build -t cve-sentry .
docker run -p 8080:8080 \
-e AUTH_SECRET=your-secret \
-e AUTH_MICROSOFT_ENTRA_ID_ID=your-id \
-e AUTH_MICROSOFT_ENTRA_ID_SECRET=your-secret \
-e AUTH_MICROSOFT_ENTRA_ID_ISSUER=your-issuer \
-e AUTH_GITHUB_ID=your-id \
-e AUTH_GITHUB_SECRET=your-secret \
-e AUTH_GOOGLE_ID=your-id \
-e AUTH_GOOGLE_SECRET=your-secret \
cve-sentry
```
该容器会:
1. 启动一个 cron 守护进程(管道每 4 小时运行一次)
2. 执行一次初始管道运行以填充数据
3. 在端口 8080 上启动 Next.js 前端
## Azure 部署
### 前置条件
- 已认证的 Azure CLI(`az`)
- 已认证的 GitHub CLI(`gh`)
- Azure 订阅
### 1. 创建 Azure 资源
```
# 资源组
az group create --name rg-cve-sentry --location centralus
# 应用服务计划(Linux,B1)
az appservice plan create \
--name plan-cve-sentry \
--resource-group rg-cve-sentry \
--sku B1 --is-linux
# Azure 容器注册表
az acr create \
--name cvesentry \
--resource-group rg-cve-sentry \
--sku Basic --admin-enabled true
# Web 应用
az webapp create \
--name cve-sentry \
--resource-group rg-cve-sentry \
--plan plan-cve-sentry \
--deployment-container-image-name cvesentry.azurecr.io/cve-sentry:latest
```
### 2. 配置容器注册表凭据
```
az webapp config container set \
--name cve-sentry \
--resource-group rg-cve-sentry \
--container-image-name cvesentry.azurecr.io/cve-sentry:latest \
--container-registry-url https://cvesentry.azurecr.io \
--container-registry-user cvesentry \
--container-registry-password $(az acr credential show --name cvesentry --query "passwords[0].value" -o tsv)
```
### 3. 设置应用程序配置
```
az webapp config appsettings set \
--name cve-sentry \
--resource-group rg-cve-sentry \
--settings \
WEBSITES_PORT=8080 \
WEBSITES_CONTAINER_START_TIME_LIMIT=600 \
AUTH_SECRET=your-generated-secret \
AUTH_URL=https://your-domain.com \
AUTH_MICROSOFT_ENTRA_ID_ID=your-client-id \
AUTH_MICROSOFT_ENTRA_ID_SECRET=your-client-secret \
AUTH_MICROSOFT_ENTRA_ID_ISSUER=https://login.microsoftonline.com/your-tenant-id/v2.0 \
AUTH_GITHUB_ID=your-github-id \
AUTH_GITHUB_SECRET=your-github-secret \
AUTH_GOOGLE_ID=your-google-id \
AUTH_GOOGLE_SECRET=your-google-secret
```
### 4. 设置 CI/CD
为 GitHub Actions 创建一个服务主体:
```
az ad sp create-for-rbac \
--name cve-sentry-deploy \
--role contributor \
--scopes /subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/rg-cve-sentry \
--sdk-auth
```
将输出的 JSON 添加为名为 `AZURE_CREDENTIALS` 的 GitHub 密钥:
```
gh secret set AZURE_CREDENTIALS --body '{ ... }'
```
每次推送到 `main` 分支都会触发自动构建与部署。
## 项目结构
```
cve-sentry/
|-- cve_sentry/ # Python threat intelligence pipeline
| |-- main.py # Entry point & scheduler
| |-- config.py # Configuration (91 product keywords)
| |-- sources/ # 13 data collectors
| | |-- base.py # Abstract collector & ThreatItem model
| | |-- msrc_rss.py # Microsoft Security Response Center
| | |-- nvd.py # NIST National Vulnerability Database
| | |-- cisa_kev.py # CISA Known Exploited Vulnerabilities
| | |-- github_advisories.py # GitHub Security Advisories (GraphQL)
| | |-- exploit_db.py # Exploit Database
| | |-- zero_day_initiative.py
| | |-- cert_eu.py # CERT-EU advisories
| | |-- epss.py # Exploit Prediction Scoring
| | +-- ... # + 4 more collectors
| |-- correlation/ # Data correlation & enrichment
| | |-- engine.py # Deduplication & merge
| | |-- mitre_attack.py # MITRE ATT&CK technique mapping
| | |-- d3fend.py # D3FEND countermeasures
| | |-- scoring.py # Risk categorization
| | +-- product_filter.py # Azure/M365 filter
| |-- analysis/ # LLM-powered analysis
| | |-- llm_summarizer.py # OpenAI / Anthropic summaries
| | +-- fallback_summarizer.py # Template-based fallback
| |-- services/ # Business logic
| | |-- risk_engine.py # Sentry Priority Score (0-10)
| | |-- delta_tracker.py # Change detection
| | |-- data_retention.py # 90-day auto-purge
| | +-- ...
| |-- reports/ # Output generation
| | |-- json_exporter.py # dashboard_data.json
| | +-- html_dashboard.py # Standalone HTML report
| +-- output/ # Generated data (gitignored)
|
|-- sentry/ # Next.js 16 frontend dashboard
| |-- auth.ts # Auth.js v5 configuration
| |-- middleware.ts # Route protection
| |-- app/
| | |-- layout.tsx # Root layout + AuthProvider
| | |-- login/ # Login page (Microsoft/GitHub/Google)
| | |-- (dashboard)/ # Protected dashboard routes
| | | |-- page.tsx # Home dashboard
| | | |-- pulse/ # Real-time threat pulse
| | | |-- threat/[id]/ # Threat detail view
| | | |-- watchlists/ # Custom watchlists
| | | |-- workflow/ # Incident management
| | | +-- ...
| | +-- api/ # 16 API route handlers
| |-- components/ # 43 React components
| +-- lib/ # Utilities & hooks
|
|-- Dockerfile # Multi-stage build (Python + Node.js)
|-- startup.sh # Container startup script
|-- .github/workflows/ # CI/CD pipeline
+-- LICENSE # AGPL-3.0
```
## Sentry 优先级评分
每项威胁会根据以下标准获得 0 到 10 的分数:
| 因素 | 分数 | 描述 |
|--------|--------|-------------|
| CISA KEV | +2.0 | 列入已知被利用漏洞列表 |
| 主动利用 | +2.0 | 提供公开利用或 POC |
| EPSS | 最高 +2.0 | `epss_score * 2.0` |
| 时效性 | 最高 +2.0 | `max(0, 2.0 - (days_old / 7) * 2.0)` |
| 供应商关键性 | +2.0 | CVSS >= 9.0 |
**优先级分类:**
- **立即处理**(8-10):需要立即修补
- **本周关注**(5-7.9):计划在本周完成修复
- **监控**(0-4.9):在下一轮周期中跟踪与审查
## API 端点
除特别注明外,所有端点均需身份验证(JWT 会话)。
| 方法 | 端点 | 描述 |
|--------|----------|-------------|
| GET | `/api/threats` | 列出威胁(可按严重性、KEV、可利用性过滤) |
| GET | `/api/threats/[id]` | 获取特定威胁详情 |
| GET | `/api/meta` | 管道元数据(统计信息,不含威胁数据) |
| GET | `/api/feed` | RSS 订阅(**公开,无需认证**) |
| GET/POST | `/api/bookmarks` | 管理收藏威胁 |
| GET/POST | `/api/watchlists` | 管理自定义观察列表 |
| GET/PUT/DELETE | `/api/watchlists/[id]` | 操作特定观察列表 |
| GET/POST | `/api/workflow` | 事件工作流管理 |
| GET/PUT/DELETE | `/api/workflow/[id]` | 操作特定事件 |
| GET/POST/DELETE | `/api/workflow/[id]/evidence` | 事件证据 |
| GET/POST/DELETE | `/api/workflow/[id]/ticket` | 工单导出 |
| GET | `/api/export` | 导出威胁数据(CSV/JSON) |
| POST | `/api/data-sync/import` | 导入威胁数据 |
| POST | `/api/data-sync/export` | 导出用于同步的数据 |
| GET/POST/DELETE | `/api/data-sync/history` | 同步历史记录 |
## 环境变量参考
### 管道(Python)
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `LLM_PROVIDER` | (空) | `openai` 或 `anthropic`,用于 AI 摘要 |
| `OPENAI_API_KEY` | - | OpenAI API 密钥 |
| `ANTHROPIC_API_KEY` | - | Anthropic API 密钥 |
| `GITHUB_TOKEN` | - | GitHub 个人访问令牌,用于更高速率限制 |
| `DAYS_LOOKBACK` | `7` | 收集 CVE 历史的天数 |
| `RETENTION_DAYS` | `90` | 自动清除的天数 |
| `SCHEDULE_INTERVAL_HOURS` | `4` | 管道运行频率 |
| `PRODUCT_FILTER_ENABLED` | `true` | 是否启用 Azure/M365 产品过滤 |
| `OUTPUT_DIR` | `./output` | 管道输出目录 |
### 仪表板(Next.js)
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `AUTH_SECRET` | - | **必需**。用于 JWT 签名的随机密钥 |
| `AUTH_URL` | - | 基础 URL(例如 `https://sentry.d3fend.me`) |
| `AUTH_MICROSOFT_ENTRA_ID_ID` | - | Entra ID 应用客户端 ID |
| `AUTH_MICROSOFT_ENTRA_ID_SECRET` | - | Entra ID 应用客户端密钥 |
| `AUTH_MICROSOFT_ENTRA_ID_ISSUER` | - | Entra ID 发行者 URL |
| `AUTH_GITHUB_ID` | - | GitHub OAuth 应用客户端 ID |
| `AUTH_GITHUB_SECRET` | - | GitHub OAuth 应用客户端密钥 |
| `AUTH_GOOGLE_ID` | - | Google OAuth 客户端 ID |
| `AUTH_GOOGLE_SECRET` | - | Google OAuth 客户端密钥 |
| `CVE_SENTRY_DATA_PATH` | auto | `dashboard_data.json` 的路径 |
## 许可证
本项目根据 [GNU Affero General Public License v3.0](LICENSE) 授权。
如果您修改了 CVE Sentry 并将其作为网络服务部署,则必须以相同的许可证公开修改后的源代码。
## 作者
**Jorge Castaneda** - [LinkedIn](https://www.linkedin.com/in/jcastanedacano/) | [GitHub](https://github.com/jcastanedacano)
标签:Azure, CISA KEV, Cloudflare, CVE, CVSS, D3FEND, EPSS, GitHub Issues, Jira, Kanban, masscan, Microsoft 365, MITRE ATT&CK, Mutation, NVD, Python, SEO, ServiceNow, XSS, 严重性分布, 产品暴露, 仅KEV, 仪表盘, 优先级评分, 厂商监控, 可视化, 后端, 威胁情报平台, 威胁监测, 安全数据源, 工作流, 异步, 数字签名, 无后门, 时间线, 最小严重性, 检测, 欺骗, 清除, 漏洞利用可用性, 漏洞情报, 漏洞趋势, 看板, 筛选器, 缓解措施, 自动化攻击, 请求拦截, 逆向工具, 隔离