如何看懂bumblebee的NDJSON输出:package、finding与scan_summary三类记录完全解析
【免费下载链接】bumblebeeRead-only developer endpoint scanner for on-disk package, extension, and developer-tool metadata, built to check exposure to known software supply-chain compromises.项目地址: https://gitcode.com/gh_mirrors/bumblebee12/bumblebee
🐝bumblebee是一个只读的开发者端点供应链安全扫描器,它把磁盘上的包、插件和开发工具元数据整理成NDJSON 输出(每行一个 JSON 对象)。扫描结束后,你会看到三类核心记录:package(发现一个包)、finding(命中一个威胁情报目录)和scan_summary(本次运行的总结)。这篇完整指南带你从零读懂这三种记录的每个字段,轻松掌握接收与排查方法。
一、先搞懂:bumblebee 的 NDJSON 长什么样
NDJSON(Newline Delimited JSON)就是“一行一个 JSON 对象”。bumblebee 每运行一次,就往输出流里逐行写入记录,格式直观、便于管道处理和日志采集:
{"record_type":"package","record_id":"package:3fa9...","package_name":"example-pkg","version":"1.2.3",...} {"record_type":"finding","record_id":"finding:81c2...","catalog_id":"advisory-2026-0042",...} {"record_type":"scan_summary","run_id":"9b1f0c2e...","status":"complete",...}默认情况下记录写入stdout,诊断信息(diagnostic)写入stderr;你也可以改用文件或 HTTP 上报,详见 docs/transport.md。
💡 小贴士:每类记录都有自己的
record_id前缀(package:、finding:、scan_summary:),一眼就能区分类型。
二、package 记录:这台机器上装了什么
record_type=package的每一行都代表 bumblebee 在某个位置发现的一个软件包。它是整个输出的“主角”,字段不多但信息密度很高:
| 字段 | 含义 | 新手关注点 |
|---|---|---|
package_name/normalized_name | 包名 / 归一化后的包名 | 匹配威胁目录用的是归一化名 |
version | 版本号 | 精确匹配的关键 |
ecosystem | 生态:npm、pypi、go、rubygems等 | 共 10 种取值 |
source_file | 证据来源文件,如pnpm-lock.yaml | 定位“怎么发现的” |
root_kind | 发现位置类型,如project_root、deep_home_root | 区分全局工具链 vs 项目 |
install_scope/package_manager | 安装作用域、包管理器 | 全局 or 项目级 |
has_lifecycle_scripts | 是否带安装钩子脚本 | 供应链投毒的高危信号 |
confidence | high/medium/low | 结论可信度分级 |
以confidence为例,它是判断记录可信度的核心:
- high—— 身份和版本都来自权威元数据;
- medium—— 身份可靠,但版本或来源不完整;
- low—— 仅配置/路径/规格引用,不能当作“已安装该精确版本”的证据。
字段结构定义在 internal/model/model.go,机器可读的校验规则见 docs/schema/v0.2.0/package-record.schema.json。各生态具体读取哪些文件(如package-lock.json、go.sum、Gemfile.lock),参见 docs/inventory-sources.md。
三、finding 记录:哪些包命中了“威胁名单”
record_type=finding是警报信号。当你传入威胁情报目录(exposure catalog)后,bumblebee 会把发现的包与目录条目做精确匹配,命中一行就产出一条 finding:
| 字段 | 含义 |
|---|---|
finding_type | 当前恒为package_exposure |
catalog_id/catalog_name | 命中的目录条目 ID 与名称(如某次投毒事件编号) |
severity | 严重级别,如critical |
ecosystem/normalized_name/version | 命中包的身份 |
evidence | 匹配证据,例如exact name+version match (version=1.2.3) |
source_file/project_path | 命中位置,方便人工复核 |
仓库自带的 threat_intel/ 目录维护了多份来自公开威胁情报的样例目录,可以直接拿来做演练:
bumblebee scan --profile deep --root "$HOME" \ --exposure-catalog ./threat_intel --findings-only--findings-only会抑制 package 记录、只保留 finding 和 summary,适合应急排查。finding 的完整字段表见 docs/schema/v0.2.0/finding-record.schema.json。
⚠️ 注意:finding 只代表“磁盘元数据上存在这个包”,不是网络、进程或文件哈希层面的入侵证据——它回答的是“谁可能被波及”,而不是“谁已经被攻击”。
四、scan_summary 记录:如何判断这次扫描是否可信
每次运行必定以一条scan_summary结尾,它相当于“运单回执”。接收端最重要的规则是:只有看到status=complete的 summary,才把本次运行的记录提升为当前状态。
关键字段速查:
| 字段 | 含义 |
|---|---|
status | complete/partial/error,见下方解释 |
package_records_emitted | 实际发出的 package 行数 |
package_records_suppressed | 被--findings-only抑制的行数 |
findings_emitted | 发出的 finding 数 |
duplicates | 运行内被去重合并的重复观察数 |
diagnostics_count | stderr 侧诊断条数 |
files_considered | 解析过的文件数 |
timed_out/duration_ms | 是否超时 / 耗时 |
roots | 本次实际扫描的根路径及类型,可作审计依据 |
http_batches_*、http_last_status | 使用 HTTP 上报时的投递统计 |
三种status的正确姿势:
- complete—— 运行完成且无终止性错误,可作为当前状态;
- partial—— 发了一部分记录但中途出错,只能当原始证据,不能替换旧状态;
- error—— 还没产出可用数据就失败了。
另外,若http_batches_failed > 0,即使其余解析成功,该次运行也不算可信快照(http_last_status=0表示最后一批连 HTTP 响应都没拿到)。这些语义细节完整记录在 docs/transport.md 的 “scan_summary completion semantics” 一节和 docs/state-model.md。
五、record_id 与 run_id:去重和跨运行关联的两把钥匙
新手最容易混淆的字段对,一次讲清:
run_id:每次运行随机生成,标识“这一趟扫描”。同一台机器两次运行的run_id必然不同。record_id:内容寻址的 SHA-256 哈希,由该记录类型的规范身份字段元组算出,跨运行、跨机器稳定。比如同一个包在同一配置下被观察两次,record_id完全一致。
因此接收端可以放心地:用(endpoint_id, run_id, record_id)做运行内去重,用record_id做跨运行关联。哈希算法与字段元组见 internal/model/model.go 中的StableID()实现,字段级清单见 docs/state-model.md。
六、3 分钟动手体验:用 selftest 看真实输出
不用等真实告警,bumblebee 内置了端到端自检,使用完全虚构的包名(如bumblebee-selftest-evil@0.0.0),不发任何网络请求:
bumblebee selftest # selftest OK (2 findings in 1ms)想亲手解剖记录流,一条命令即可:
bumblebee scan --profile baseline > inventory.ndjson然后用任意工具按record_type过滤三种记录即可。内置测试用的样例包、威胁目录等夹具位于 cmd/bumblebee/selftest/fixtures/,可对照阅读。
七、新手常见疑问 FAQ
Q1:为什么我的 package 行数比预期少?看duplicates——同一来源文件的重复观察会被合并;再看--findings-only是否会抑制 package 记录(此时package_records_suppressed为正数属正常)。
Q2:package_records_emitted为 0 一定有问题吗?不一定。--findings-only运行时它就是 0 且完全合法;但status=complete且无该选项、却 0 条记录,说明该 profile 下没有可解析的清单文件——这也是一个有效的空状态。
Q3:baseline 和 project 的结果能互相“抵消”吗?不能。两个 profile 是独立人群(population),baseline 扫描不能删除 project 观察到的包,反之亦然。deep只用于按需事件排查,不应用于更新当前状态。详见 docs/state-model.md 的 “Promotion rule”。
Q4:字段变了怎么办?每条记录都带schema_version(当前为0.2.0)。接收端应按schema_version分版本解析,旧版本0.1.0的 schema 也仍保留在 docs/schema/v0.1.0/。
总结
| 记录类型 | 一句话理解 | 典型用途 |
|---|---|---|
package | “这台机器有这个包” | 构建端点清单、历史趋势 |
finding | “它命中了威胁目录” | 事件响应、暴露面排查 |
scan_summary | “这次扫描可信吗” | 状态提升、运行审计 |
读懂这三类记录,你就掌握了 bumblebee NDJSON 输出的全部关键信息:用package建清单、用finding追暴露、用scan_summary保信任。配合 README.md 的快速开始章节和 docs/state-model.md 的接收端建模建议,即可从“看到输出”进阶到“用好输出”。🎯
【免费下载链接】bumblebeeRead-only developer endpoint scanner for on-disk package, extension, and developer-tool metadata, built to check exposure to known software supply-chain compromises.项目地址: https://gitcode.com/gh_mirrors/bumblebee12/bumblebee
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考