VulnFeed 2.0:构建 Zero-Server 漏洞仪表盘(Level 2 发布)
Source: Dev.to
问题
大多数漏洞仪表盘要么:
- 费用过高 – 企业级 SaaS 工具价格高昂
- 功能受限 – 只专注于单一生态系统或发行版
- 隐私噩梦 – 追踪你的数据、查询和团队
- 过于复杂 – 需要后端基础设施来维护
我们想要一种根本不同的方案。
介绍 Onyx Intelligence
Onyx 是一个完全静态、零服务器的漏洞仪表盘,聚合来自 25+ 个来源(CISA、Red Hat、所有主流 Linux 发行版、npm、PyPI、Maven、RubyGems、Cargo、Composer 等)的数据,呈现在一个美观、交互式的界面中。
可以把它看作 VulnFeed 的 Level 2 进化版 —— 你喜欢的一切功能,且更强大。
关键统计
- 📊 25+ 个漏洞数据来源
- 🔄 通过 GitHub Actions 每 6 小时自动更新
- 🏗️ 零后端需求(GitHub Pages 部署)
- 🔒 零追踪,零数据收集
- 🎨 美观的玻璃拟态 UI,支持明暗主题
- 📱 完全响应式(移动端、平板、桌面)
- 🧠 资产暴露扫描(可选)
工作原理(技术实现)
数据收集管道
一切从一个每 6 小时运行一次的 GitHub Actions 工作流开始:
# .github/workflows/osv-feed-update.yml
schedule:
- cron: '0 */6 * * *' # Every 6 hours
以下是幕后发生的事情:
# scripts/fetch_osv_data.py
import requests
import json
from datetime import datetime
# Fetch from OSV.dev for all ecosystems
ecosystems = ['npm', 'PyPI', 'Maven', 'Cargo', 'Go', 'NuGet', 'Composer', 'RubyGems']
for ecosystem in ecosystems:
response = requests.get(
'https://api.osv.dev/v1/query',
json={'package': {'ecosystem': ecosystem}}
)
# Validate and deduplicate
vulnerabilities = response.json()
# Store as clean JSON
with open(f'data/{ecosystem.lower()}.json', 'w') as f:
json.dump(vulnerabilities, f)
# Also fetch CISA KEV, Red Hat, Linux distros
# Everything gets merged, validated, and deployed
输出为干净、结构化的 JSON 文件,供前端使用。
前端渲染
在客户端,它是纯原生 JavaScript,没有任何框架或臃肿代码:
// Load vulnerability data from static JSON files
async function loadVulnerabilities() {
const response = await fetch('/data/vulnerabilities.json');
return response.json();
}
// Build interactive visualizations with Chart.js
function renderSeverityChart(vulnerabilities) {
const severityData = {
labels: ['Critical', 'High', 'Medium', 'Low'],
datasets: [{
data: [
vulnerabilities.filter(v => v.severity === 'CRITICAL').length,
vulnerabilities.filter(v => v.severity === 'HIGH').length,
vulnerabilities.filter(v => v.severity === 'MEDIUM').length,
vulnerabilities.filter(v => v.severity === 'LOW').length
]
}]
};
new Chart(ctx, { type: 'doughnut', data: severityData });
}
// Real‑time filtering and search (no backend calls!)
function searchVulnerabilities(query, severity, days) {
return vulnerabilities.filter(v =>
(v.description.toLowerCase().includes(query.toLowerCase()) ||
v.id.includes(query)) &&
(severity === 'ALL' || v.severity === severity) &&
(isWithinDays(v.published, days))
);
}
没有 API 调用。没有服务器请求。仅靠静态资源和客户端逻辑完成繁重工作。
部署魔法
部署几乎是如此简单,宛如魔法:
- Commit changes to your fork.
- GitHub Actions workflow triggers automatically.
- Python scripts fetch fresh data.
- Static HTML/CSS/JS gets generated.
- Deployed to GitHub Pages automatically.
你的仪表盘已上线:yourusername.github.io/Onyx-Intelligence/
我们构建的关键特性
✅ 多源聚合
不再需要为不同漏洞来源打开 25 个浏览器标签页,所有内容集中在一个地方:
// Single search across CISA, Red Hat, npm, PyPI, Maven, etc.
const allVulnerabilities = [
...cisaKEV,
...redHatAdvisories,
...npmVulnerabilities,
...pypiVulnerabilities,
...mavenVulnerabilities,
// ... 20+ more sources
];
// Now search once and get results from everywhere
const results = allVulnerabilities.filter(v =>
v.id.includes('CVE-2024-') ||
v.packages.includes('lodash') ||
v.source === 'CISA'
);
✅ 智能过滤
高级过滤,无需后端复杂性:
// Critical vulnerabilities from the last 30 days
const criticalRecent = vulnerabilities.filter(v =>
v.cvss >= 7.0 &&
daysOld(v.published) v.ecosystem === 'npm');
// Combine filters
const targetedResults = vulnerabilities.filter(v =>
(v.severity === 'CRITICAL' || v.severity === 'HIGH') &&
v.ecosystem.includes('Linux') &&
daysOld(v.published) <= 7
);
✅ 资产暴露扫描器
可选功能,扫描 IP 和域名,使用多个情报源:
// Scan an IP against Censys, Shodan, AbuseIPDB, VirusTotal
async function scanAsset(ipOrDomain) {
const results = await Promise.all([
fetch(`/api/scan?ip=${ipOrDomain}&provider=censys`),
fetch(`/api/scan?ip=${ipOrDomain}&provider=shodan`),
fetch(`/api/scan?ip=${ipOrDomain}&provider=abuseipdb`),
fetch(`/api/scan?ip=${ipOrDomain}&provider=virustotal`)
]);
return {
censys: await results[0].json(),
shodan: await results[1].json(),
abuseipdb: await results[2].json(),
virustotal: await results[3].json()
};
}
API 密钥安全存储在 GitHub Secrets 中——永不在前端代码中泄露。
✅ 隐私至上设计
零追踪。零数据收集。仅是纯粹、诚实的软件:
// Only localStorage for theme preference
localStorage.setItem('theme', 'dark');
localStorage.setItem('lastViewed', 'npm');
// Everything else is session‑only, in‑memory
const sessionData = {
currentFilters: { severity: 'HIGH', days: 30 },
selectedVulnerability: null
};
// No Google Analytics, Mixpanel, Segment, etc.
✅ 美观 UI
我们不仅仅是构建了一个工具——我们打造了一个高端外观的产品:
/* Glassmorphism cards */
.vulnerability-card {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 1.5rem;
transition: all 0.3s ease;
}
.vulnerability-card:hover {
background: rgba(255, 255, 255, 0.15);
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.vulnerability-card {
background: rgba(30, 27, 75, 0.2);
border-color: rgba(255, 255, 255, 0.1);
}
}
/* Responsive grid */
@media (max-width: 768px) {
.grid {
grid-template-columns: 1fr;
}
}
流畅的动画,明暗主题,完全响应式。
入门指南(真的,只需 5 分钟)
步骤 1:Fork 仓库
(后续步骤请参见原文。)