rust-secure-code/cargo-auditable

GitHub: rust-secure-code/cargo-auditable

将 Rust 项目的完整依赖树嵌入编译后的二进制文件,使生产环境中的可执行文件可在脱离源码的情况下进行漏洞审计和 SBOM 追踪。

Stars: 802 | Forks: 37

## cargo-auditable 了解用于构建 Rust 可执行文件的确切 crate 版本。在生产环境中大规模审计二进制文件的已知错误或安全漏洞,零账簿开销。 其工作原理是将 JSON 格式的依赖树数据嵌入到编译后可执行文件的专用 linker section 中。 官方支持 Linux、Windows 和 Mac OS。从 v0.6.3 版本起也支持 [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly)。所有其他 ELF 目标应该也能工作,但未在 CI 中测试。 最终目标是让 Cargo 自身将此信息编码到二进制文件中。目前有一个关于在 Cargo 内部实现的 RFC,本项目为其铺平了道路:https://github.com/rust-lang/rfcs/pull/2801 ## 使用方法 ``` # 安装工具 cargo install cargo-auditable cargo-audit # 构建在二进制文件中嵌入依赖列表的项目 cargo auditable build --release # 扫描二进制文件以查找漏洞 cargo audit bin target/release/your-project ``` `cargo auditable` 适用于任何 Cargo 命令。所有参数均按原样传递给 `cargo`。 ### 在 nightly Rust 上 在 nightly 版本上,我们可以利用 Cargo 的[原生 SBOM 前身](https://doc.rust-lang.org/cargo/reference/unstable.html#sbom) 来更准确地记录依赖项: ``` CARGO_BUILD_SBOM=true cargo +nightly auditable build -Z sbom --release ``` 由于 [Cargo 中的一个 bug](https://github.com/rust-lang/cargo/issues/15695),如果您在同一个项目中也曾使用过不带 `-Z sbom` 的 `cargo auditable`,您可能需要先执行 `touch src/*` 或 `cargo clean`。 ### 通过其他工具 如果您没有直接调用 `cargo` 且无法更改其调用方式,可以将 `cargo auditable` 用作 `cargo` 的直接替代品。详见[此处](REPLACING_CARGO.md)。 ### 用于 Github 发布 [`cargo dist`](https://github.com/axodotdev/cargo-dist) 提供了对 `cargo auditable` 的可选支持,详见[此处](https://axodotdev.github.io/cargo-dist/book/supplychain-security/index.html)。 ## 采用情况 Microsoft 内部使用 `cargo auditable`,并曾维护[Go 的数据提取库](https://github.com/microsoft/go-rustaudit)。 多个 Linux 发行版使用 `cargo auditable` 构建其 Rust 软件包:[Alpine Linux](https://www.alpinelinux.org/)、[NixOS](https://nixos.org/)、[openSUSE](https://www.opensuse.org/)、[Void Linux](https://voidlinux.org/)、[Chimera Linux](https://chimera-linux.org/) 和 [Wolfi OS](https://wolfi.dev)。如果您从它们的仓库安装软件包,您可以对其进行审计! [Chainguard](https://chainguard.dev/) 在其 [rust 基础容器](https://images.chainguard.dev/directory/image/rust/overview) 中包含了 `cargo auditable`,并提供了默认的 `cargo` 包装器以始终调用 `cargo auditable`,因此使用此容器构建的 Rust 应用程序默认是可审计的。 ## 常见问题 ### 这会使我的二进制文件膨胀吗? 简而言之,不会。即使对于拥有 400 多个条目的大型依赖树,嵌入的依赖列表占用也不到 4kB。这通常仅占二进制文件大小的 1/1000 到 1/10,000。 ### 我可以让 `cargo` 总是使用 `cargo auditable` 进行构建吗? 可以!例如,在 Linux/macOS 等系统上,将以下内容添加到您的 `.bashrc` 中: ``` alias cargo="cargo auditable" ``` 如果您使用的 shell 不是 bash,或者使用别名不可行,请[参阅此处](REPLACING_CARGO.md)。 ### 有没有什么工具可以使用这些数据? #### 漏洞报告 * [cargo audit](https://crates.io/crates/cargo-audit) v0.17.3+ 可以检测二进制文件中的此数据并报告漏洞。详情请参阅[此处](https://github.com/rustsec/rustsec/tree/main/cargo-audit#cargo-audit-bin-subcommand)。 * [trivy](https://github.com/aquasecurity/trivy) v0.31.0+ 可检测二进制文件中的此数据并报告漏洞。端到端示例请参阅 [v0.31.0 发布说明](https://github.com/aquasecurity/trivy/discussions/2716)。 * [grype](https://github.com/anchore/grype) v0.83.0+ 可检测二进制文件和容器镜像中的此数据并报告漏洞。 * [osv-scanner](https://github.com/google/osv-scanner/) v2.0.1+ 在扫描容器镜像时会[读取此数据](https://github.com/google/osv-scalibr/pull/377)。 #### 恢复依赖列表 * [syft](https://github.com/anchore/syft) v1.15.0+ 支持恢复此数据并将其转换为各种格式。旧版本需要 `--catalogers all` CLI 选项。 * [docker](https://docs.docker.com/build/metadata/attestations/sbom/) 支持将 CycloneDX 文档嵌入到容器镜像中。如果您使用 `docker buildx build --tag /: --attest type=sbom --push .` 构建容器镜像,并在 `Dockerfile` 中使用 `cargo auditable` 构建 rust 二进制文件,那么附加到容器镜像的 SBOM 证明将包含您的 rust 依赖项。此功能由 [BuildKit Syft scanner](https://github.com/docker/buildkit-syft-scanner) 提供支持。 * [blint](https://github.com/owasp-dep-scan/blint) v2.1.3+ 可以恢复此数据并将其输出为 CycloneDX。 * [wasm-tools](https://github.com/bytecodealliance/wasm-tools) v1.227.0+ 可以从 WebAssembly 中恢复此数据。请尝试 `wasm-tools metadata show`。 * [rust-audit-info](https://crates.io/crates/rust-audit-info) 从二进制文件中恢复依赖列表并以 JSON 格式打印。 * [auditable2cdx](https://crates.io/crates/auditable2cdx) 从二进制文件中恢复依赖列表并以 CycloneDX 格式打印。 ### 我可以使用不同语言编写的工具读取此数据吗? 可以。该数据格式专为与其他实现的互操作性而设计。事实上,解析它只需要 [5 行 Python 代码](PARSING.md)。有关解析数据的文档,请参阅[此处](PARSING.md)。 此外,Syft 可以读取并将其转换为多种格式。`auditable2cdx` 可以将其转换为 CycloneDX,大多数工具都能理解该格式。这种转换使您甚至可以将此数据提供给无法修改的工具。 ### 数据格式具体是什么? 数据格式由 [此处](cargo-auditable.schema.json) 的 JSON schema 描述。 JSON 经过 Zlib 压缩,并放置在名为 `.dep-v0` 的 linker section 中。 您可以在[此处](PARSING.md) 找到有关解析它的更多信息。 ### 嵌入式平台怎么办? 对于连一个字节都腾不出来的嵌入式平台,不应在可执行文件中添加任何内容。相反,它们应该将每个可执行文件的哈希值记录在数据库中,并将该哈希值与其 Cargo.lock、编译器和 LLVM 版本、构建日期等关联起来。这将是一个出色的 Cargo 包装器或插件。既然这可以通过一个 5 行的 shell 脚本完成,编写该工具就留给读者作为练习。 ### 这会影响可复现构建吗? 该数据格式专门设计为不破坏可复现构建。它不包含时间戳,并且生成的 JSON 经过了排序,以确保在多次编译之间是相同的。如果说有什么影响的话,这实际上*有助于*可复现构建,因为您现在知道了给定二进制文件的所有版本。 ### 这会泄露任何敏感信息吗? 不会。所有 URL 和文件路径都经过编辑,但 crate 名称和版本按原样记录。目前,panic 消息已经披露了所有这些信息甚至更多。此外,您很可能在法律上也有义务披露特定开源 crate 的使用情况,因为 MIT 和许多其他许可证都有此要求。 ### 记录编译器版本呢? 编译器本身从 v1.73 及更高版本开始[嵌入了它](https://github.com/rust-lang/rust/pull/97550)。 在旧版本中,它已经存在于调试信息中。在 Unix 上,您可以运行 `strings your_executable | grep 'rustc version'` 来查看它。 ### 跟踪静态链接的 C 库版本呢? 问得好。我认为目前它们没有以任何合理的方式暴露出来。这将是一个很好的补充,但对于初始发布来说不是必需的。我们可以稍后以向后兼容的方式添加它。采用 [`-src` crate 约定](https://internals.rust-lang.org/t/statically-linked-c-c-libraries/17175?u=shnatsel) 会使其自然发生,并且还会带来其他好处,因此这可能是最佳途径。 ### 这能防止供应链攻击吗? 不能。请使用 [`cargo-vet`](https://github.com/mozilla/cargo-vet) 或 [`cargo-crev`](https://github.com/crev-dev/cargo-crev) 来防御此类攻击。 [软件物料清单](https://en.wikipedia.org/wiki/Software_supply_chain) (SBOM) 并不能防止供应链攻击。它们甚至不能用于评估此类攻击被发现后的影响,因为任何有价值的恶意库都会将自己从 SBOM 中移除。这几乎适用于所有语言和构建系统,而不仅仅是 Rust 和 Cargo。 在应对供应链攻击时,不要依赖 SBOM! ### 将此功能上游到 Cargo 中的阻碍是什么? [关于 Cargo 自身此功能的 RFC](https://github.com/rust-lang/rfcs/pull/2801) 已被 Cargo 团队[推迟](https://github.com/rust-lang/rfcs/pull/2801#issuecomment-2122880841),直到[更基础的 SBOM RFC](https://github.com/rust-lang/rfcs/pull/3553) 完成。 该 RFC 现已实现,并可通过[不稳定特性](https://doc.rust-lang.org/cargo/reference/unstable.html#sbom) 使用。这为再次提交将此功能引入 `cargo` 本身的 RFC 敞开了大门。
标签:AI工具, Cargo插件, Claude, CVE检测, DevSecOps, ELF, Homebrew安装, Rust, SBOM, WebAssembly, 上游代理, 二进制分析, 云安全监控, 云安全运维, 依赖管理, 可审计性, 可视化界面, 嵌入式数据, 数据集, 文档安全, 生产环境安全, 硬件无关, 网络流量审计, 跌倒检测, 软件物料清单, 通知系统, 通知系统, 零开销, 静态分析