darkyzowo/venderscope
GitHub: darkyzowo/venderscope
一个为GRC团队提供的持续被动供应商风险情报平台,替代年度评审实现实时风险监测与审计支持。
Stars: 1 | Forks: 0
# VenderScope
[](https://venderscope.vercel.app)
[](https://venderscope-api.onrender.com/docs)
[](https://www.linkedin.com/in/zarak-hassan7/)
[](https://github.com/darkyzowo/venderscope/releases/tag/v3)
VenderScope 是一个为 GRC 和信息安全专业人员构建的持续、被动供应商风险情报平台。它不再依赖年度回顾式评估,而是 24/7 持续监控您的供应商资产,跨越多个威胁情报源,并在出现风险漂移时实时呈现结果——具备完整的用户认证、生产级安全加固,以及云 PostgreSQL 后端。
## 最新维护更新
本仓库已完成后端安全、前端逻辑和响应式体验的全面清理与稳定化。
- **移动端优先响应式重构** — 仪表盘、供应商详情、认证界面、访客扫描、卡片、图表、模态框、页脚及相关布局已重建,确保在现代 iPhone 和 Pixel 宽度下良好运行,使用 `100dvh`、安全区域感知间距、堆叠操作行以及更紧凑的移动面板间距。
- **分析师笔记重设计与加固** — 笔记区域已重建以匹配现有产品风格,笔记输入在后端现为标准化明文(不可信输入),回归测试覆盖控制字符剥离以及 SQL 风格载荷被当作惰性文本处理。
- **更安全的后端配置** — 环境加载集中化,CORS/来源验证使用共享配置而非易出错的硬编码值,且认证来源检查遵循相同的允许来源规则。
- **邮件/测试防护** — `EMAIL_ENABLED=0` 可禁用外发邮件,保留的测试域名会被屏蔽,后端测试绑定到专用的 SQLite 测试数据库,防止破坏性测试设置触及生产 Neon 数据。
- **扫描与仪表盘逻辑修复** — `全部扫描` 现在使用真实批量端点,仪表盘风险阈值与后端逻辑对齐,缺失供应商的详情页会优雅降级而非卡在加载状态。
- **前端清理** — 路由级懒加载与供应商分块减少了入口包体,未使用的依赖已被移除,`follow-redirects` 被固定在漏洞范围之上,审计/构建/代码检查路径已清理。
本次通过后的验证结果:
- `python -m pytest -q` → `63 passed`
- `npm run lint` → 通过
- `npm run build` → 通过
## v3.7 新功能 — UI/UX 重塑与品牌标识
v3.7 是一个以前端为重点的发布版本,聚焦视觉打磨与品牌标识,尚未涉及后端变更。
### VS Wordmark Logo
自定义的 `VSLogo` 组件以内联 SVG 渲染官方 VS 标识,并带有顺序描边动画——V 的左腿、右腿与 S 各自独立绘制,使用 `pathLength="1"` 与 `stroke-dashoffset` 关键帧。标识出现在仪表盘头部、供应商详情导航栏与页脚,取代所有之前的文本与图标式品牌标记。
### 登录与注册页面重设计
两个认证页面均被完全重新设计,采用分层背景系统与交错入场动画:
- **循环背景描边** — 四条弯曲的 SVG 路径以不同步时序进行描边绘制并循环(7–10 秒周期),直接呼应 VS 标识的绘制动画,背景始终保持活跃但不干扰阅读。
- **雷达脉冲环** — 页面加载时,三个同心环从卡片中心向外扩展并淡出,产生“系统初始化”的声纳效果,仅播放一次。
- **变形环境光球** — 浮动渐变紫色光球现在会同步 `border-radius`、位置与缩放,在有机块状与星云感之间切换。
- **点阵覆盖层** — 固定径向渐变点阵覆盖视口,作为微妙的底层结构。
- **玻璃拟态卡片** — 使用 `backdrop-filter: blur(28px)`、半透明背景与紫色边框强调。
- **交错入场** — 每个元素依次淡入并抬起,使用双 `requestAnimationFrame` 技术确保绘制时序稳定。
- **响应式认证外壳** — 登录/注册采用防滚动 `100dvh` 布局,替代固定 `100vh`,避免移动端浏览器刘海与软键盘破坏布局。
### 文本颜色标准化
现在所有页面统一使用四层文本调色板:
| 令牌 | 十六进制 | 对比度 | 用途 |
|------|----------|--------|------|
| `--hi` | `#f0f0ff` | 14:1 | 标题、关键数值 |
| `--mid` | `#b8b8d0` | 6.5:1 | 正文文本、描述 |
| `--lo` | `#8080aa` | 4.8:1 | 标签、元数据、提示 |
| `--lo2` / `#44445a` | — | 装饰性 | 分隔点与短横线 |
### GRC 打磨(v3.6 延续)
- **供应商卡片审核状态** — 卡片现在展示实时“审核逾期 X 天”(琥珀色)或“审核:MMM D”(柔和色)信息行。
- **仪表盘审核到期徽标** — 重新设计为琥珀色玻璃拟态徽标,带时钟图标与悬停提示,列出逾期供应商名称。
- **PDF 导出增强** — 供应商报告现在包含审核计划章节与风险接受表(发现引用、类型、理由、审核人、到期日、活跃/过期状态)。
## v3.6 新功能 — GRC 工作流功能
v3.6 引入了四项专为 GRC 与信息安全专业人员设计的功能,在无需额外成本的前提下将 VenderScope 从监控仪表盘转变为轻量级风险管理工具。
### 分析师笔记 — 供应商证据日志
附加在每个供应商记录上的时间有序、仅追加的笔记日志,专为 GRC 团队在整个供应商关系中记录风险决策、对话、后续行动与审核结果而设计。
- **按供应商日志** — 可在供应商详情页直接添加带时间戳的自由文本笔记。
- **不可变设计** — 笔记可删除但不可编辑,以保持审计完整性。
- **Ctrl+Enter 快捷提交** — 无需离开上下文即可快速提交。
- **包含在 PDF 导出中** — 笔记作为“分析师笔记”章节出现在供应商风险报告中,便于在 ISO 27001 与 SOC 2 审核中作为证据。
- **完全隔离** — 笔记仅对创建者可见,不跨用户共享。
### 周期性审核计划 — 不再错过供应商审核
GRC 团队有义务按既定周期审核供应商。本功能将这一义务内置于工具本身,而非依赖外部电子表格或日历。
- **设置审核间隔** — 可为每个供应商选择 30 / 60 / 90 / 180 天或年度周期。
- **标记为已审核** — 单击按钮将当前时间戳记录为最近审核日期。
- **实时审核状态** — 供应商详情页显示“下次审核:[日期]”(绿色)或“逾期 X 天”(琥珀色)。
- **仪表盘指示器** — 任一供应商逾期时,统计行会出现“审核到期”计数徽标,悬停时显示供应商名称。
- **无需邮件依赖** — 完全内置于应用,即使未配置 Resend 域名也能使用。
### 风险接受工作流 — 可记录、可审计的风险决策
该工具在 GRC 能力方面最大的缺口在于:仅识别风险是不够的,团队必须正式记录为何选择接受而非修复。这是 ISO 27001(A.5.20)与 SOC 2 的直接要求。
- **每次事件接受** — 每个风险事件流中均有“接受风险”按钮。
- **结构化接受表单** — 记录理由、审核人姓名与到期日(默认 90 天,最长 1 年)。
- **琥珀色“ACCEPTED”徽标** — 已接受事件显示独立徽标,悬停可查看详情。
- **自动过期** — 到期后的接受记录变为非活动状态,事件以原始严重性徽标重新浮现,提示重新审核。
- **一键撤销** — 可提前撤销接受决定。
- **需要关注逻辑** — 仅当存在未接受的上升事件时,仪表盘才会将供应商标为需要关注。
- **完整审计追踪** — 每次接受与撤销均记录在追加式审计日志中,包含用户 ID、时间戳与事件引用。
风险登记导出 — 用于审计资料包的 CSV
GRC 团队常需手动从扫描结果填充风险登记。本功能通过一键操作关闭这一差距。
- **“导出登记”按钮** — 位于仪表盘头部。
- **12 列 CSV** — 供应商名称、域名、数据敏感度、技术评分、有效暴露评分、风险等级、评分变化、最后扫描时间、审核周期、导出日期。
- **客户端生成** — 无需服务端往返,立即生成可下载的 `.csv`。
- **文件名含日期** — `vendorscope_risk_register_YYYY-MM-DD.csv`。
- **直接映射风险登记** — 列与标准 ISO 27001 风险处理计划及 SOC 2 供应商管理证据对齐。
### 业务上下文权重 — 有效暴露评分
_(v3.5.x 中已发布,此处为完整性说明)_
原始 CVE 评分将支付处理器与营销工具同等对待。业务上下文权重通过应用数据敏感度倍数来修正技术风险评分。
- **按供应商设置敏感度层级** — 无(×0.8)、标准(×1.0)、PII(×1.4)、金融/认证(×1.6)、健康(×1.8)、关键基础设施(×2.0)。
- **有效暴露评分** — 调整后的评分作为仪表盘、供应商卡片与 PDF 导出的主要指标。
- **药丸选择器** — 与应用设计系统一致的样式,不使用原生浏览器控件。
## v3.5 新功能
### 访客模式 — 注册前即可试用
VenderScope 现在允许任何人无需注册即可快速查询 CVE 漏洞。
- **无需账户** — 可从登录页通过“尝试访客模式 →”直接使用。
- **仅 CVE 扫描** — 查询 NIST NVD 获取与供应商名称相关的已知漏洞。
- **即时风险评分** — 使用与完整扫描相同的加权 0–100 评分引擎,基于 CVE 信号。
- **PDF 下载** — 可导出带水印的访客报告,明确标注为部分扫描。
- **零数据持久化** — 结果即时计算并返回,不写入数据库。
- **清晰限制提示** — 访客会看到明确说明,告知缺失内容(漏洞数据、Shodan、合规性、画像),并邀请注册以获取完整扫描。
### v3.5 安全加固
在访客模式上线前进行了完整安全审计,并已解决以下问题:
- **IP 绕过速率限制(高危)** — `_real_ip()` 曾使用 `XFF[0]`(客户端可控)作为速率限制依据。由于未认证端点仅依赖此限制,该问题关键。修复为使用 `XFF[-1]`(Render 附加、不可伪造),与 v3.1 中修复的审计日志一致。
- **缺失内容安全策略(中危)** — 在 `vercel.json` 中添加了 CSP,作为 Vercel 响应头(`frame-ancestors 'none'`、`connect-src` 锁定至 API 源、`object-src 'none'`)。
- **55/55 安全测试通过** — 新增 23 个测试,覆盖 SSRF 阻断、零数据库写入验证、输入校验、XML 注入处理、无效严重性/评分/事件限制以及 PDF 生成。
## v3.1.5 新功能
### 认证与多用户支持
- **JWT 认证** — 访问令牌存储在内存中(15 分钟过期),刷新令牌存储在 `httpOnly`、`SameSite=None; Secure` 的 Cookie 中(7 天,单次使用轮换)。
- **注册 / 登录 / 注销** — 完整的认证流程,使用 bcrypt 密码哈希(12 轮)。
- **每用户供应商隔离** — 每个数据库查询均限定于 `current_user.id`,确保用户无法查看或扫描其他用户的供应商。
- **静默令牌刷新** — `AuthContext` 在挂载与 401 时自动刷新令牌,保持会话无缝。
- **密码复杂度规则** — 最小 12 位,至少包含一个大写字母与一个数字,前端与后端双重 enforced。
- **注册确认邮件** — 通过 Resend HTTP API 发送欢迎邮件(开发环境使用 Gmail SMTP 回退)。
### 安全加固
- **JTI 黑名单** — 单次使用的刷新令牌;每次轮换会撤销前一个令牌的 JWT ID;注销会立即使当前刷新令牌 JTI 失效。
- **追加式审计日志** — 所有安全事件(`login.success`、`login.failed`、`logout`、`register.success`、`vendor.added`、`vendor.deleted`、`vendor.scanned`、`export.pdf`、`account.deleted`、`token.refreshed`)均记录 IP 地址与时间戳。
- **安全头中间件** — 包含 `X-Content-Type-Options`、`X-Frame-Options`、`Referrer-Policy`、`Permissions-Policy`、`Strict-Transport-Security`(生产环境启用 HSTS)。
- **FRONTEND_URL 启动验证** — 若 `FRONTEND_URL` 缺失或配置错误,生产环境将拒绝启动。
- **UUID 供应商 ID** — 主键使用 UUID(非顺序整数),防止 IDOR 枚举。
- **bcrypt DoS 防护** — 登录时强制限制密码最大长度,防止十亿哈希攻击。
- **全部 20 个审计漏洞已修复**(详见 `docs/security-architecture.md`)。
### 基础设施
- **PostgreSQL(Neon)** — 生产环境迁移至云 PostgreSQL,开发环境保留 SQLite。
- **pg8000 纯 Python 驱动** — 兼容 Python 3.14+,无 C 依赖,在 Render 上无需构建工具即可运行。
- **连接池** — `pool_pre_ping`、`pool_size=5`、`max_overflow=10`,确保云连接稳定。
- **已吊销令牌清理** — APScheduler 每 6 小时清理一次过期的 JTI 黑名单条目。
### UI 与账户管理
- **删除账户** — 两步确认流程(警告 → 输入“DELETE” → 密码重新确认),级联删除所有供应商数据。
- **页脚** — 包含隐私政策、条款与安全文档链接,细微处提供删除账户入口。
- **法律与安全文档** — `/privacy`、`/terms`、`/security` 页面由 Markdown 渲染。
## v3.1 新功能
### 安全加固(二次审计)
- **真实 IP 速率限制** — uvicorn 启用 `--proxy-headers`,正确解析 Render 负载均衡后的每个客户端 IP。修复前所有用户共享同一速率限制桶。
- **CSRF 源验证** — `logout`、`refresh` 与 `delete_account` 端点现在校验 `Origin`/`Referer` 头与 `FRONTEND_URL`,作为 CORS 之上的纵深防御层。
- **密码删除前重新确认** — 注销账户需当前密码,防止短暂令牌泄露导致误删。
- **强化 SSRF 防护** — `_is_safe_domain()` 现已阻止 URL 编码 IP(如 `127%2E0%2E0%2E1`)、十进制/八进制表示、IPv6 映射 IPv4 地址及云元数据端点(GCP、Azure、阿里巴巴);手动跟随重定向链(最多 3 跳,每跳校验域名)。
- **HIBP 精确域名匹配** — 替换子串匹配(曾产生误报),改用精确匹配 + www 规范化,并引入 1 小时进程内缓存,避免每次扫描都重新获取 1MB 泄露列表。
- **注入防护** — PDF 导出中对所有外部数据应用 `xml.sax.saxutils.escape`,邮件模板中应用 `html.escape`。
- **配额文件线程安全** — 使用 `threading.RLock()` 保护 `ThreadPoolExecutor` 扫描工作线程的并发读写。
- **刷新令牌生命周期** — 从 30 天缩短至 7 天(行业标准的轮换周期)。
- **陈旧配置清理** — 移除 SQLite 的 `DATABASE_URL`(若在 `render.yaml` 中设置,曾在生产环境中静默覆盖 PostgreSQL 密钥)。
### 告警(代码完成 — 待上线生产域名)
- **Resend HTTP API** — 重构告警调度器;若配置了已验证的发送域名则使用 Resend,否则自动回退至 Gmail SMTP。
- **每用户告警邮件** — 扫描告警现在发送至供应商所有者的注册,而非硬编码地址。
## 功能
### 监控与情报
- **持续被动监控** — 自动每 24 小时扫描供应商,零人工干预。
- **多源情报聚合** — 同时从 HIBP、NVD(国家漏洞库)、Companies House 与 Shodan 汇总风险信号。
- **实时风险评分** — 加权严重性评分引擎(0–100),含 CRITICAL/HIGH/MEDIUM/LOW 分类。
- **业务上下文权重** — 按供应商设置数据敏感度倍数,生成反映业务风险而非仅技术信号的“有效暴露评分”。
- **风险评分漂移时间线** — 面积图展示供应商风险态势随时间的变化。
- **供应商画像自动发现** — 被动识别描述、认证方式与 2FA 支持(来自公开页面)。
- **第三方认证归属** — 区分供应商直接持有的证书与引用其基础设施提供商的证书。
- **英国本土治理** — 集成 Companies House,标记财务困境、逾期申报与董事变更。
- **暴露基础设施检测** — Shodan 标记危险开放端口(RDP、SMB、MongoDB 等)。
- **24 小时智能缓存** — 重复扫描即时返回;夜间调度器强制刷新数据。
- **两阶段合规发现** — 抓取供应商页面寻找 ISO 27001、SOC 2、GDPR、Cyber Essentials、PCI DSS 等证据;必要时回退至 Google CSE。
- **已验证安全联系人** — 通过 RFC 9116 的 `security.txt`、页面抓取与网络搜索查找安全与隐私联系人。
- **扫描配额追踪器** — 实时横幅显示剩余 Google CSE 配额,每日 UTC 午夜重置。
### GRC 工作流(v3.6)
- **分析师笔记** — 每个供应商的时间有序证据日志,包含在 PDF 导出中,审计完整性保障。
- **周期性审核计划** — 为每个供应商设置审核周期,仪表盘展示逾期情况。
- **风险接受工作流** — 结构化表单记录风险接受理由、审核人与有效期,完整审计追踪。
- **风险登记导出** — 一键导出 12 列 CSV,适配 ISO 27001 风险处理计划与 SOC 2 供应商管理证据。
## 技术栈
| 层级 | 技术 |
|------|------|
| 后端 | Python 3.11+、FastAPI、SQLAlchemy 2.0、APScheduler、Uvicorn |
| 数据库 | PostgreSQL(Neon,生产)/ SQLite(本地开发) |
| 数据库驱动 | pg8000(纯 Python,兼容 Python 3.14+) |
| 认证 | JWT(python-jose)、bcrypt、httpOnly Cookie |
| 前端 | React 19、Vite 8、React Router 7、TailwindCSS 3、Axios |
| 情报源 | HIBP API、NVD/NIST API、Companies House API、Shodan API |
| 合规 | Google Custom Search API、BeautifulSoup4、security.txt |
| 邮件 | Resend HTTP API(生产)/ Gmail SMTP(本地开发) |
| PDF 导出 | ReportLab |
| 速率限制 | SlowAPI |
## 情报来源
| 来源 | 检测内容 |
|------|----------|
| **HaveIBeenPwned** | 供应商域名在所有已知数据泄露中的暴露情况 |
| **NVD(NIST)** | 与供应商产品及服务相关的 CVE |
| **Companies House** | 英国公司状态、逾期申报、董事辞职 |
| **Shodan** | 供应商基础设施上暴露的端口与服务 |
| **Google CSE** | ISO 27001、SOC 2、GDPR、Cyber Essentials、PCI DSS 等外部认证证据 |
| **供应商画像** | 主页 meta 描述、认证方式、2FA 支持(被动抓取) |
## 架构
```
VenderScope/
├── backend/
│ ├── main.py # FastAPI app, CORS, security headers, lifespan
│ ├── models.py # Vendor, RiskEvent, RiskScoreHistory, User,
│ │ # RevokedToken, AuditLog, VendorNote,
│ │ # RiskAcceptance (SQLAlchemy)
│ ├── database.py # PostgreSQL + SQLite connection (pg8000, ssl_context)
│ ├── scheduler.py # 24hr scan + 6hr JTI cleanup + 10min keep-alive
│ ├── routers/
│ │ ├── auth.py # Register, login, refresh, logout, /me, delete account
│ │ ├── vendors.py # Vendor CRUD, notes, review scheduling (all user-scoped)
│ │ ├── acceptances.py # Risk acceptance lifecycle (create, list, revoke)
│ │ ├── intelligence.py # Scan trigger endpoints
│ │ ├── dashboard.py # Aggregate stats, needs attention, overdue reviews
│ │ ├── export.py # PDF export (Content-Disposition sanitised)
│ │ └── quota.py # Google CSE quota status
│ └── services/
│ ├── scanner.py # Concurrent scan orchestrator + caching
│ ├── auth_service.py # JWT encode/decode, password hash, get_current_user
│ ├── audit.py # Append-only security event recorder
│ ├── alerts.py # Resend HTTP API + Gmail SMTP dispatcher
│ ├── compliance_discovery.py # Two-stage compliance + cert discovery
│ ├── vendor_profile.py # Passive vendor description, auth & 2FA discovery
│ ├── quota.py # Google CSE daily quota tracker
│ ├── hibp.py # HIBP breach intelligence
│ ├── nvd.py # NVD CVE intelligence
│ ├── companies_house.py # UK governance checks
│ ├── shodan_service.py # Exposed infrastructure checks
│ └── pdf_export.py # ReportLab PDF generator
└── frontend/
└── src/
├── pages/
│ ├── Login.jsx # Auth: login form + deleted account banner
│ ├── Register.jsx # Auth: register with client-side complexity rules
│ ├── Dashboard.jsx # Main vendor overview
│ ├── VendorDetail.jsx # Per-vendor risk detail + profile panel
│ └── DocPage.jsx # Lightweight markdown renderer for /privacy, /terms, /security
├── components/
│ ├── VendorCard.jsx # Risk score card
│ ├── ScoreChart.jsx # Lightweight SVG drift timeline chart
│ ├── EventFeed.jsx # Risk events list
│ ├── AddVendorModal.jsx # Add vendor form
│ ├── CompliancePanel.jsx # Compliance posture with badge system
│ ├── QuotaBanner.jsx # Daily scan quota tracker
│ ├── Footer.jsx # Links to docs + delete account trigger
│ └── DeleteAccountModal.jsx # 2-step account deletion (type "DELETE" to confirm)
├── contexts/AuthContext.jsx # JWT access token in memory, silent refresh
├── docs/
│ ├── privacy.md
│ ├── terms.md
│ └── security.md
└── api/client.js # Axios client, auth headers, token refresh
```
## 安装设置
### 先决条件
- Python 3.11+
- Node.js 18+
- NVD、Companies House、Shodan、Google Custom Search 的 API 密钥
### 后端
```
cd backend
pip install -r requirements.txt
```
创建 `backend/.env`:
```
# Intelligence APIs
NVD_API_KEY=your_key
COMPANIES_HOUSE_API_KEY=your_key
SHODAN_API_KEY=your_key
GOOGLE_CSE_API_KEY=your_key
GOOGLE_CSE_ID=your_cse_id
# Email(本地:Gmail SMTP;生产:Resend 验证域名)
GMAIL_ADDRESS=your@gmail.com
GMAIL_APP_PASSWORD=your_app_password
EMAIL_ENABLED=1
# 设置 EMAIL_ENABLED=0 以在本地测试运行或随时完全禁用外发邮件
# RESEND_API_KEY=re_... # 拥有已验证的发送域名时取消注释
# RESEND_FROM_EMAIL=VenderScope
ALERT_THRESHOLD=70
# 认证
JWT_SECRET=your_64_char_hex_secret
# 前端(必须与生产环境中已部署的前端 URL 匹配)
FRONTEND_URL=http://localhost:5173
# 数据库(生产用 PostgreSQL,本地用 SQLite)
DATABASE_URL=sqlite:///./vendorscope.db
# DATABASE_URL=postgresql://user:pass@host/db?sslmode=require
```
```
uvicorn main:app --reload
# API: http://127.0.0.1:8000
# 文档: http://127.0.0.1:8000/docs
```
### 前端
```
cd frontend
npm install
npm run dev
# http://localhost:5173
```
创建 `frontend/.env.local`:
```
VITE_API_URL=http://127.0.0.1:8000/api
```
## 认证机制
VenderScope 采用 **双令牌 JWT 方案**:
| 令牌 | 存储位置 | 过期时间 | 用途 |
|------|----------|----------|------|
| 访问令牌 | JS 内存(永不存入 localStorage) | 15 分钟 | 每个 API 请求的 Bearer 认证 |
| 刷新令牌 | `httpOnly`、`SameSite=None; Secure` 的 Cookie | 7 天 | 自动签发新访问令牌(单次使用) |
**令牌轮换** — 每次刷新会生成新的刷新令牌,并立即在数据库中撤销前一个令牌的 JWT ID(JTI)。重放的刷新令牌会被拒绝。
**注销** — 立即将当前刷新令牌的 JTI 加入黑名单,令牌即使被截获也无效。
**会话持久化** — 页面加载时,`AuthContext` 会调用 `/api/auth/refresh` 从 Cookie 中静默恢复会话,无需重新登录。
**密码策略** — 最小 12 位,至少包含一个大写字母和一个数字,前后端双重强制。
**注册确认邮件** — 通过 Resend HTTP API 发送(开发环境使用 Gmail SMTP 回退)。
## 安全架构
VenderScope 已通过完整安全审计,关键控制如下:
| 控制项 | 实现方式 |
|--------|----------|
| 认证 | JWT + httpOnly Cookie 刷新令牌 |
| 授权 | 每个数据库查询限定于 `current_user.id` |
| IDOR 防护 | 未授权访问返回 404(而非 403) |
| 暴力破解防护 | 所有认证端点均限速(SlowAPI) |
| 密码存储 | bcrypt,12 轮 |
| 密码策略 | 最少 12 位,含大写字母与数字 |
| DoS 防护 | 登录时限制密码最大长度(防十亿哈希攻击) |
| XSS | 访问令牌仅存于内存,刷新令牌使用 httpOnly Cookie |
| SSRF | RFC1918 阻断列表、云元数据端点、URL 解码绕过预防、IPv6 映射 IPv4 检测、3 跳重定向链验证(每跳域名校验) |
| SQL 注入 | SQLAlchemy ORM(全程参数化查询) |
| 头部注入 | PDF Content-Disposition 文件名使用正则清洗 |
| 安全头 | X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy、HSTS(生产) |
| 审计追踪 | 追加式 AuditLog 表,记录 X-Forwarded-For |
| 密钥管理 | 所有凭据存于环境变量;`.env` 已加入 .gitignore |
| 令牌重放 | JTI 黑名单 + 单次使用刷新令牌 |
| CSRF | 对所有使用 Cookie 的端点校验 `Origin`/`Referer` 头 |
| 内容注入 | PDF 中外部数据使用 XML 转义;邮件模板使用 HTML 转义 |
| 会话令牌 | 供应商 ID 使用 UUID(非顺序整数) |
| 输入校验 | 所有输入经 Pydantic 校验,摄入时标准化域名 |
| 启动检查 | 生产环境校验 `FRONTEND_URL`,缺失或错误则拒绝启动 |
完整审计记录与修复说明:`docs/security-architecture.md`
## 风险评分
评分采用权重平均法,取按严重性排序的前 5 个事件,并引入计数倍增因子(供应商信号越多,最高 1.4 倍),上限为 100。
| 严重性 | 数值 |
|--------|------|
| CRITICAL | 100 |
| HIGH | 70 |
| MEDIUM | 40 |
| LOW | 15 |
评分 ≥ `ALERT_THRESHOLD`(默认 70)的供应商会向其注册邮箱触发告警邮件。
## 合规发现
**阶段 1 — 页面抓取(免费)**:获取供应商主页、安全页、隐私政策与信任中心,查找 ISO 27001、SOC 2、GDPR、Cyber Essentials、 DSS 及数据处理协议的证据。
**阶段 2 — 网络搜索回退(消耗 Google CSE 配额)**:对未在自有页面发现的证书,执行定向 Google 自定义搜索。
### 第三方归属检测
VenderScope 会识别常见误报——供应商引用其基础设施提供商的证书而非自身。匹配结果按句子/元素粒度分析。若某证书关键词的所有出现均处于第三方归属语境,则标记为 **“Via infra partners”**,而非 **“Verified”**。
| 徽章 | 含义 |
|------|------|
| **Verified** | 在供应商自有网站找到直接归属的证据 |
| **External source** | 通过网络搜索找到证据 |
| **Via infra partners** | 证书属于基础设施提供商,非供应商本身 |
| **No evidence** | 未找到任何证据 |
### 扫描配额
Google 自定义搜索每日免费 100 次查询。每次完整智能扫描最多消耗 14 个单位(≈ 7 次免费扫描)。配额耗尽时自动回退至标准扫描(仅页面抓取)。配额每日 UTC 午夜重置。
## 供应商画像自动发现
每次扫描中,VenderScope 免费被动收集三项数据:
**描述** — 从 `og:description` 或 `` 抓取。
**认证方式** — 从公开页面识别 11 类认证机制(SSO/SAML、OpenID Connect、OAuth 2.0、Passwordless、Social Login、Okta/Auth0、基于密码等)。
**2FA 支持** — 检测到 MFA/2FA/TOTP/认证器关键词即返回“是”,否则返回“未检测到”(而非“否”),因为缺乏证据不等于不存在。
## 已知限制
**Render 免费层冷启动**:空闲后首次请求约 50 秒延迟。保持活跃的 ping(每 10 分钟一次)可缓解。
**JS 渲染的信任中心**:使用 Vanta 等动态加载证书的供应商,其 scraper 获取原始 HTML,并依赖 Google CSE 回退。
**生产环境邮件告警**:Render 免费层禁止外发 SMTP。Resend HTTP API 已就绪,一旦在 `RESEND_FROM_EMAIL` 配置了已验证发送域名即可激活;在此之前,生产环境跳过告警并通过 Gmail SMTP 本地投递。
**安全调度器范围**:24 小时后台调度器扫描所有供应商;按用户调度(仅提醒自身供应商)已在路线图中。
## 路线图
- [x] 多源被动情报引擎
- [x] 风险评分漂移时间线
- [x] Companies House 英国集成
- [x] PDF 审计导出(ISO 27001 兼容)
- [x] Shodan 暴露基础设施检测
- [x] 24 小时智能缓存 + 夜间调度器
- [x] 并发 API 抓取
- [x] 合规态势自动发现
- [x] 两阶段认证检测(抓取 + Google CSE)
- [x] 第三方认证归属检测
- [x] 已验证安全联系人发现
- [x] 每日扫描配额追踪器
- [x] 供应商画像自动发现
- [x] 完整 JWT 认证(v3)
- [x] 每用户供应商隔离(v3)
- [x] bcrypt 密码哈希与复杂度规则(v3)
- [x] JTI 黑名单 / 单次使用刷新令牌(v3)
- [x] 追加式审计日志(v3)
- [x] 安全头中间件(v3)
- [x] UUID 供应商 ID(v3)
- [x] PostgreSQL(Neon)+ pg8000 迁移(v3)
- [x] Resend HTTP API 邮件调度器(v3,待发送域名)
- [x] 账户删除(含级联)与密码重新确认(v3)
- [x] 法律与安全文档页面(v3)
- [x] 真实 IP 速率限制(v3.1,位于 Render 代理后)
- [x] CSRF 源验证(v3.1)
- [x] SSRF 重定向链验证 + 云元数据阻断列表(v3.1)
- [x] HIBP 精确域名匹配 + 泄露列表缓存(v3.1)
- [x] PDF 与邮件内容注入预防(v3.1)
- [x] 风险差值仪表盘 — 评分漂移、需要关注视图、供应商卡片差值徽标(v3.1)
- [x] 合规发现改进 — 扩展路径探测、站点地图回退、更广泛的关键词(v3.1)
- [x] 访客模式 — 无认证 CVE 扫描并支持 PDF 下载,零数据持久化(v3.5)
- [x] 内容安全策略(CSP)应用于 Vercel 前端(v3.5)
- [x] 业务上下文权重 — 数据敏感度倍数生成有效暴露评分(v3.5.x)
- [x] 分析师笔记 — 时间有序证据日志,包含在 PDF 导出中(v3.6)
- [x] 周期性审核计划 — 每供应商审核间隔与仪表盘逾期指示(v3.6)
- [x] 风险接受工作流 — 结构化记录与完整审计追踪(v3.6)
- [x] 风险登记 CSV 导出 — 一键 12 列导出(v3.6)
- [x] VS Wordmark 标识与动画描边 — 应用于仪表盘、页脚、供应商详情(v3.7)
- [x] 登录/注册重设计 — 循环描边、脉冲环、变形光球、玻璃拟态卡片(v3.7)
- [x] 全站文本颜色标准化 — 四层对比调色板(v3.7)
- [x] 供应商卡片审核状态行 + 仪表盘审核到期琥珀色徽标(v3.7)
- [x] PDF 导出增强 — 包含审核计划与风险接受表(v3.7)
- [ ] 供应商对比视图 — 并排对比两家供应商的风险态势
- [ ] 可共享风险报告 — 有时效的公开只读供应商快照链接
- [ ] 批量 CSV 导入 — 一次性导入多个供应商
- [ ] 内置评分变更告警(无需邮件)
- [ ] 每用户告警配置(阈值、渠道、Webhook)
- [ ] 生产环境邮件告警(需已验证的 Resend 发送域名)
- [ ] 每用户调度器范围
- [ ] 异步任务队列(Celery + Redis)
## 部署
### 后端(Render)
生产环境所需环境变量:
```
DATABASE_URL postgresql://...neon.tech/neondb?sslmode=require&channel_binding=require
JWT_SECRET 64-char hex string
FRONTEND_URL https://venderscope.vercel.app
NVD_API_KEY
COMPANIES_HOUSE_API_KEY
SHODAN_API_KEY
GOOGLE_CSE_API_KEY
GOOGLE_CSE_ID
GMAIL_ADDRESS (optional — local email fallback)
GMAIL_APP_PASSWORD (optional)
EMAIL_ENABLED 1 (set to 0 to disable all outbound email)
ALERT_THRESHOLD 70
RENDER true (enables HSTS + SameSite=None cookies)
```
### 前端(Vercel)
```
VITE_API_URL https://venderscope-api.onrender.com/api
```
## 动机
源于管理 50+ 供应商审计的实际经验。传统 GRC 工具(如 Vanta、SecurityScorecard、BitSight)年费数千美元且为被动响应。VenderScope 是开源的、支持英国 Companies House,并持续被动运行——它负责监控供应商,您无需亲为。
## 作者
**Syed Zarak Hassan**
合规分析师与网络安全硕士在读
[LinkedIn](https://linkedin.com/in/zarak-hassan7) · [GitHub](https://github.com/darkyzowo)
_本项目为独立开源项目。数据来源于公共 API,决策前请咨询合格的安全专业人士。_
标签:API文档, CORS, GitHub Advanced Security, GRC, PostgreSQL, SEO, 供应商风险, 后端安全, 响应式设计, 威胁情报, 安全加固, 开发者工具, 持续监控, 搜索引擎查询, 测试用例, 生产环境, 移动优先, 自定义脚本, 被动监控, 请求拦截, 逆向工具