
威胁情报观察站,聚合 CISA KEV、ThreatFox、URLhaus 和 MalwareBazaar 数据源,支持搜索、变更跟踪以及 STIX/CSV/JSONL 导出。
一个以证据为先的威胁观测系统,将当前源状态、实质变更事件和运行获取遥测在语义上彼此分离。缺失、过期、禁用或不可用的数据仍保持可见的缺失状态。界面绝不用演示记录或推断归因来替代。
当前版本强化了证据日期和设备本地确认状态,使所有重要的读取失败与成功的零结果状态清晰区分,稳定了关联请求,并加强了证据抽屉、有界调查过滤器、源解读、移动端控件和导出统计。每个动画重放标记仍然对应一条保留的 NEW、UPDATED 或 REMOVED 事件;它不是装饰性的网络流量。

Pulse —— 跨源关联、源健康和当前状态分析。

Replay —— 按页有界重建已保留的 NEW、UPDATED 和 REMOVED 变迁。
其他实时界面包括近似的公网 IP 基础设施地理位置,以及第一方 URLhaus / MalwareBazaar 证据视图。这些界面在本 README 中有意不使用占位或重复截图来表示。
生产截图来自线上 v1.2.0 观测台,是保留源信息的截图。它们为展示而裁剪并调整大小/压缩;所展示的证据、时间戳、计数、IOC 值和界面状态均未重新生成或替换。
生产 Worker 由 Cloudflare D1 提供支撑。源凭据仍是仅限服务器的 Cloudflare Worker 机密,绝不在浏览器中要求提供。
1.2.022.13.0 或更新版本此部署以 demand-driven(按需驱动)模式运行。仓库现在直接面向标准 Cloudflare Workers;v1.2.0 中有意不启用计划触发器,因此应用并不声称持续采集。未来的调度器可以在完成独立的正确性和运行验证之后调用同一个 runIngestionCycle() 操作。
浏览器在首次使用以及打开期间每五分钟发出一次显式的有界维护请求:
POST /api/ingest
↓
runIngestionCycle()
↓
configuration → TTL → backoff → D1 lease → fetch → normalize → validate
↓
snapshot cache + current observations + material events + cycle statistics
普通读取是分离且本地的:
GET /api/observations → D1 current state, scoped before pagination
GET /api/search → D1 current state, scoped before pagination
GET /api/kev → D1 current CISA catalog
GET /api/events → D1 material change ledger
GET /api/geo → local observations + bounded cached IP enrichment
上述 GET 路由均不调用源适配器。如果此项目日后获得真正受支持的调度器,它可以调用同一个 runIngestionCycle() 操作,而无需创建第二个刷新实现。
覆盖范围按源显示。有界 API 绝不会被呈现为完整目录。
DB 绑定拥有多个独立数据集:
threat_source_cache 和 threat_source_cache_chunks:每个源最新经过验证的快照,以代际键控的块存储。observations:每个稳定源标识下最新的规范化当前状态。它保留首次摄取时间、最近源出现时间、上次实质变更、当前哈希、修订次数和最近摄取结果。observation_events:有意义的 NEW、UPDATED 和具有合理依据的 REMOVED 证据事件。先前和当前的规范化负载、哈希以及确定性的字段差异使先前状态可重建。source_fetch_log:有界的获取尝试遥测,不包含响应体或凭据。source_ingest_cycles:每次刷新的有界计数,涵盖已获取、有效、拒绝、新增、更新、未变化和已删除记录。source_refresh_lease:基于 D1 的短期每源租约,防止多个隔离实例重复上游刷新。ingestion_runtime:最新整体摄取周期健康状况。geo_ip_cache:经过验证的近似 IP 地理位置结果以及有界的负缓存条目。成功结果 30 天后过期;失败的查询五分钟后重试。过期的 D1 行会在 GEO 请求期间被机会式清理,隔离内存回退上限为 2,000 条。运行时模式定义位于 db/schema.ts。初始化会在创建依赖索引之前将新的当前状态列添加到现有 observations 表。
这些问题有意彼此不同:
observations 和经过验证的源快照回答这个问题。/api/observations?window=... 按上游 observedAt 过滤当前观测。observation_events 和 /api/revisions 回答这个问题。当前状态不会被不准确地描述为七天历史表。实质事件账本保留七天。获取和周期遥测保留两天,且每个源上限为 200 行。七天未再次出现的非目录当前观测会被清理。CISA 始终保持最新,因为每次成功响应都是完整目录;从该目录中移除的行在清理前保留 30 天。
目前只有 CISA 的缺失能产生 REMOVED 事件,因为其适配器获取的是完整当前目录。有界的 ThreatFox、URLhaus 或 MalwareBazaar 结果中缺少某条记录不被视为删除。
未变化的出现会推进当前的 lastObservedInSnapshotAt/lastIngestedAt,但不会创建事件或递增 revisionCount。lastChangedAt 在后续未变化的出现中得以保留。
Exploited 视图区分:
dateAdded 落在显式 TODAY、7D 或 30D 范围内的记录。亚天级观测台窗口绝不会被呈现为 CISA 精度。当前目录支持服务端搜索、厂商、产品、最新添加、勒索软件关联、添加日期过滤和不透明游标分页。它显示 CVE、厂商、产品、漏洞名称、添加日期、截止日期、勒索软件关联和所需操作。它不会凭空编造 CVSS 分数。
内容哈希覆盖规范化证据字段,而非观测台簿记。哈希变化会产生 UPDATED 事件,包含先前的规范化负载、新的规范化负载、先前/新哈希,以及针对以下内容的确定性差异:
来源抽屉查询 /api/revisions?id=...,并展示当前哈希、上次实质变更、修订次数、保留事件和字段级差异。易变的摄取时间戳不会出现在内容差异中。
抽屉还为每条接受的记录展示一个版本化的证据轨迹:已接受的规范化字段、保持缺失的可选字段、仅用于显示的变换、分类依据和稳定身份依据。该轨迹只描述保留的证据。被拒绝的上游值不会被保留,也绝不会被赋予合成的观测台身份。拒绝情况以每周期聚合计数单独表示,带有有界的字段和原因代码;该模式之前收集的旧周期被标记为缺少细分,而不是被重构。
Recent Events 只显示实质变更。完整 CISA 刷新后,它不会发出数百条未变化的 SEEN 行。这些出现情况在源周期统计中汇总。
默认的 Briefing 视图将保留的实质事件账本与仅存储在当前浏览器中的版本化确认游标进行比较。首次使用和已清空的存储被标记为初始基线,而非新活动。如果保存的游标早于保留账本,界面会声明无法证明完整的增量。
确认操作绝不会变更或删除服务器事件。游标可以导出/导入为 JSON 以便有意的设备转移;它不会被呈现为账户同步状态,生成的设备标识也绝不会发送到服务器。
Briefing 总计描述当前返回的账本页,并标记为“所示/按页有界”。它们不会被呈现为完整保留账本的总计。
导入的确认时间戳经过严格验证,并在存储或比较之前规范化为 UTC ISO-8601。浏览器存储被视为可选的:被阻止或失败的本地存储会产生一个紧凑的内联错误,绝不会使 Briefing 崩溃。
Export 工作台将已加载的经过验证的可见页面格式化为 CSV、JSONL、STIX 2.1、去武器化文本或证据清单(包含应用的策略和可用的记录哈希)。活动的本地搜索和源范围会带入 Export。空的源允许列表导出零条记录。STIX 将 CISA CVE 表示为 Vulnerability 对象,将经过验证的文件哈希(包括 MalwareBazaar SHA-256 值)表示为 Indicator 对象。已选择、已发出和不支持的计数各不相同;不支持的记录在捆绑包元数据中披露,而不是静默丢弃。Export 不进行任何上游采集。缺失的置信度保持缺失,跨源分歧保持为独立记录,已删除的账本事件绝不会静默进入当前状态导出。这些产物是证据传输,而非防火墙拦截建议。
过期的源使用有界的重试延迟:1、2、5、15 和 30 分钟。有效的较大 Retry-After 会被遵守,上限为一小时。退避期间,有效的先前快照作为过期数据提供;空的失败源保持离线。
获取之前,符合条件的源会获取一个短期的条件 D1 租约。另一个隔离实例无法替换未过期的持有者,因此只有一个刷新会继续。如果 D1 不可用,系统会明确报告降级的仅快照模式和隔离内存租约;该回退不会被描述为分布式。
当前观测、源特定工作区、本地搜索、CISA 目录、实质事件和记录修订均使用有界的服务端游标查询。源和种类约束在排序和分页之前应用。游标编码稳定的排序元组,经过长度/字符/模式验证,并在格式错误时以 HTTP 400 失败关闭。浏览器绝不会仅仅为了本地分页而接收完整的七天数据集。
API 限流器是一个限定在 Worker 隔离实例内的内存固定窗口计数器。它被如实报告为尽力而为的隔离本地保护,而非全局权威的 Cloudflare 速率限制。普通读取按报告的客户端 IP 限制为每分钟 120 次请求;摄取有独立的每分钟六次请求桶,地理有独立的每分钟十二次请求桶。D1 写入不会被添加到每次读取中仅仅为了夸大这项控制。
POST /api/ingest — 显式的按需维护周期;遵守 TTL、退避和 D1 租约。GET /api/observations?window=24h&scope=urlhaus&limit=100&cursor=... — 分页的本地当前状态窗口;有效范围是 all、urlhaus、malwarebazaar 和 infrastructure。GET /api/search?q=indicator&window=24h&scope=urlhaus&limit=100&cursor=... — 分页的范围限定本地搜索;零上游调用。GET /api/kev?limit=50&q=...&vendor=...&product=...&ransomware=known&addedSince=YYYY-MM-DD&cursor=... — 完整的当前 CISA 目录。GET /api/events?limit=50&cursor=... — 实质事件账本。GET /api/revisions?id=...&limit=50&cursor=... — 当前记录及保留的修订。GET /api/correlations?id=... — 数据集层面的当前状态精确指标对等记录。GET /api/geo?window=24h — 仅从经过验证的本地公网 IP 观测中派生候选地址,每次请求最多检索 12 个未缓存的提供商结果,并返回带有来源的缓存近似 WGS84 点。本地 Cloudflare 开发从 .dev.vars 读取仅限服务器的凭据。将 .dev.vars.example 复制为 .dev.vars,并只填写你获授权使用的源:
THREATFOX_AUTH_KEY=
URLHAUS_AUTH_KEY=
MALWAREBAZAAR_AUTH_KEY=
生产凭据必须存储为 Cloudflare Worker 机密,绝不能提交到源码或暴露给客户端的 GitHub 变量。应用仅通过 Workers 运行时绑定面访问它们。它们绝不能出现在 NEXT_PUBLIC_*、客户端组件、HTML、日志、夹具或已提交文件中。
仓库直接面向标准 Cloudflare Workers。wrangler.jsonc 是 Worker 配置的权威来源,并声明了一个名为 DB 的草稿 D1 绑定。Wrangler 4 会在首次经过身份验证的部署时自动配置该 D1 资源,并在后续部署中保持绑定链接。没有提交任何账户特定的 D1 标识符。
开发与生产命令:
npm ci
npm run dev
npm run build
npm run preview
# authenticated Cloudflare session / CI only
npm run deploy
GitHub Actions 验证在每次拉取请求和推送到 main 时运行。生产部署通过 deploy production 工作流刻意手动执行,并需要名为 CLOUDFLARE_API_TOKEN 和 CLOUDFLARE_ACCOUNT_ID 的仓库机密。这可以防止未经审查的分支或不完整的凭据设置自动发布。
npm ci
npm audit --omit=dev --audit-level=high
npm audit --audit-level=high
npm test
npm run lint
npm test 是受支持的测试入口点:它在确定性套件之前执行完整的生产构建,以便工件级别的客户端机密隔离可以检查 dist/client。在干净检出上直接运行 node --test 有意省略了该必需的构建工件。测试涵盖:严格的日历和确认时间戳解析、可选的设备存储、稳定的关联依赖、规范化证据、规范标签哈希、实质事件创建、未变化的重新摄取、先前负载保留、上次变更持久性、字段差异、事件保留和账本缺口、证据轨迹、空源导出策略、STIX 表示/计数完整性、TTL/退避资格、刷新租约、服务端分页前范围限定接线、专用 GEO/近期 KEV 查询、游标验证、读取路径隔离、源覆盖、外部引用策略、速率限制准确性、源故障隔离和客户端机密隔离。
GEO 模式只绘制经过验证的公网 IPv4/IPv6 观测。专用 D1 查询在请求的当前状态窗口中选取符合条件的 IP 记录,而不是复用通用观测页。响应报告候选记录总数以及是否达到了 2,000 条记录的安全上限。调用方不能提供任意的上游目标或 IP 列表。GeoJS 是固定的主要提供商,FreeIPAPI 是固定的回退提供商;任意的上游 URL 是不可能的。应用通过 12 地址请求上限、30 天 D1 成功缓存、五分钟重试缓存和专用路由限流器来约束外部工作。每个绘制点都保留其实际的提供商来源,并可以打开其底层本地记录。
以 MIT 许可证发布。参见 LICENSE。
选择 GEO 模式会导致服务器将每个经过验证的公网 IP 候选地址连同普通的 HTTPS 请求元数据发送给 GeoJS,并在需要回退时发送给 FreeIPAPI。因此,这些提供商可以观察到哪些公网地址被查询。私有、保留、文档和客户端提供的地址绝不会被发送;关系模式不执行任何地理位置请求。
Replay 工作区按观测台检测时间顺序重建当前页的实质账本变迁。NEW、UPDATED 和 REMOVED 的动画完全由存储的事件驱动。它明确按页有界,并不声称重建完整的历史快照或网络流量量。
源自 Natural Earth 的 world-atlas 包提供本地底图。地图对共置 IP 进行聚类,支持悬停详情和点击查看来源,并报告已地理位置定位、已排除、不可用和待处理计数。私有、保留、文档、组播和其他非公网范围在任何提供商调用之前即被排除。
IP 地理位置被明确呈现为近似的基础设施位置。它不是行为者位置、事件来源、国籍、所有权认定或归因主张。失败的富化操作保持缺失;应用绝不生成替代坐标。
默认可视化仍然是一个交互式力导向的个体观测场,连接到其来源和明确提供的恶意软件家族。画布支持节点拖拽、场平移、缩放、动画链路流量和直接来源检查。GEO 是独立的证据界面,具有自己的来源和失败语义。
| 源 | 凭据 | TTL | 实际覆盖 |
|---|
| CISA KEV | 无 | 30 分钟 | 完整的最新已验证目录 |
| ThreatFox | THREATFOX_AUTH_KEY | 15 分钟 | 请求的 24 小时 IOC 窗口 |
| URLhaus | URLHAUS_AUTH_KEY | 15 分钟 | recent 端点返回的最新 500 条记录 |
| MalwareBazaar | MALWAREBAZAAR_AUTH_KEY | 15 分钟 | 端点返回的最新 100 条元数据记录 |
GET /api/status — 源、当前状态、新鲜度、摄取模式、周期、租约和速率限制语义。