Booyaka101/rust-symbol-audit

GitHub: Booyaka101/rust-symbol-audit

一个 GitHub Action,对 Rust 依赖升级 PR 进行符号级能力 diff、编译时代码审查、供应链溯源和安全公告检查,并通过有状态审查棘轮机制实现可靠的合并门禁。

Stars: 0 | Forks: 0

# rust-symbol-audit [![测试](https://static.pigsec.cn/wp-content/uploads/repos/cas/6b/6b52945adbf8d9e421fe243515ae54cfbd3da263f16b1eabda37cdc0b797b8eb.svg)](https://github.com/Booyaka101/rust-symbol-audit/actions/workflows/tests.yml) [![发布](https://img.shields.io/github/v/release/Booyaka101/rust-symbol-audit?sort=semver&color=orange)](https://github.com/Booyaka101/rust-symbol-audit/releases) [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-rust--symbol--audit-2ea44f?logo=github)](https://github.com/marketplace/actions/rust-symbol-audit) [![许可证: MIT](https://img.shields.io/github/license/Booyaka101/rust-symbol-audit?color=blue)](LICENSE) 一个 GitHub Action,将 Rust 依赖升级转化为**您可以真正设卡的 capability-creep 审查**。 它回答了版本号无法回答的问题:*这次升级 —— 该 crate 是否开始打开 sockets,生成进程,在我的构建机器上运行代码,更改了发布者,或者携带了已知漏洞?* ## 五条通道 1. **Symbols** — 构建新旧版本,对比 **v0-demangled** 的 `.rlib` 符号,并标记新引用的敏感 API(`std::process::Command`、`TcpStream`、`std::fs`、`env::var`、类似于 secret 的名称、`reqwest`/`rustls`…)。 2. **Compile-time surface** — 新增或修改的 **`build.rs`**,切换到 **`proc-macro = true`**,或者新的 **`links =`** 原生库。这些是*在编译时于您的构建机器上*运行的代码 —— 并且评论会展示**实际的 build-script 差异**,而不仅仅是“它变了”。Symbol 对比对此视而不见。 3. **Dependency tree** — 升级**新拉入到您构建中的** crates,突出显示那些具有已知网络 / 进程 / 加密 / FFI 能力的 crates。 4. **Provenance** *(网络)* — 通过 crates.io API:由**不同账号**发布的版本、**没有源代码仓库**的 crate,或者**被撤回 (yanked)** 的版本。这是真实供应链攻击最初期的模样。 5. **Advisories** *(网络)* — 通过 OSV.dev (RustSec):针对确切新版本的已知漏洞。 ## 棘轮机制 —— 为什么您可以一直开启它 在每次 PR 中对升级重新报警的启发式方法会被静音处理。rust-symbol-audit 是**有状态的**:在 `.rust-symbol-audit/reviews.toml` 中签署放行某个版本一次,未来的审计就会对该版本保持绿色通过 —— 因此每一次红色警报都是真正的**新增且未审查的**内容。这就是让 `fail-on` 足够可靠以至于能阻断合并的原因。 ``` # .rust-symbol-audit/reviews.toml — capability 签核 [[review]] crate = "reqwest" version = "0.12.0" reviewed_by = "alice" notes = "http client; network capability expected" ``` PR 评论中包含一个可复制粘贴的**签署放行代码片段 (sign-off snippet)**,适用于每个未审查的 crate(或者运行 `scripts/review.sh `),因此批准一次升级只需一次粘贴。关键是,签署放行**仅**抑制能力相关的通道 —— 后续的**安全公告或 provenance 变更绝不会因为旧的审查记录而被隐藏**。 ## 用法 将 [`examples/pr-audit.yml`](examples/pr-audit.yml) 复制到 `.github/workflows/pr-audit.yml`: ``` on: pull_request: paths: ["Cargo.lock"] permissions: contents: read pull-requests: write # post/update the comment jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } - uses: booyaka101/rust-symbol-audit@v3 with: github-token: ${{ secrets.GITHUB_TOKEN }} fail-on: "none" # or critical/high/medium to block merges ``` 要自动合并无聊的 Dependabot 升级并拦下有风险的升级,请参阅 [`examples/auto-merge.yml`](examples/auto-merge.yml)(基于 `recommendation` 输出为 GitHub 自动合并设卡)。 ### 输入 | 输入 | 默认值 | 描述 | |---|---|---| | `github-token` | — | 通常是 `secrets.GITHUB_TOKEN`。用于发布/更新评论。 | | `max-crates` | `10` | 最多审计这么多数量的变更 crates;其余的将被列为“未审计”。 | | `fail-on` | `none` | 在 `medium`/`high`/`critical` 级别使检查失败。`none` = 仅提供公告建议。 | | `config` | `.rust-symbol-audit.toml` | 用于抑制已知良性信号的允许/忽略规则。 | | `reviews` | `.rust-symbol-audit/reviews.toml` | 审查账本(即棘轮机制)。 | | `check-provenance` | `true` | 查询 crates.io 以获取发布者/仓库/撤回 (yank) 变更(需要网络)。 | | `check-advisories` | `true` | 查询 OSV.dev 以获取 RustSec 公告(需要网络)。 | ### 输出 | 输出 | 描述 | |---|---| | `changed` | 是否有任何 crate 版本在 `Cargo.lock` 中发生了变更。 | | `tier` | 最高风险等级:`critical`/`high`/`medium`/`none`。 | | `flagged` | 带有被标记信号的 crates,以逗号分隔。 | | `build-script-changes` | 构建脚本被新增/修改的 crates 数量。 | | `advisories` | 发现的已知 RustSec/OSV 公告数量。 | | `recommendation` | `auto-merge`(等级为 none)或 `review` —— 据此为 Dependabot 自动合并设卡。 | | `report` | 机器可读的 `audit-report.json` 证据文件的路径。 | ### 抑制误报 — `.rust-symbol-audit.toml` 参见 [`examples/rust-symbol-audit.toml`](examples/rust-symbol-audit.toml): ``` ignore_crates = ["libc", "windows-sys"] # never flag these [allow] reqwest = ["TcpStream", "hyper", "rustls"] # suppress these findings for this crate ``` `ignore`/`allow` 会永久静音某个信号;而**账本**一次只签署放行一个版本(并且依然会显示未来的安全公告)。如果表示“允许此 crate 永远拥有此能力”,请使用 `allow`;如果是表示“我审查了确切的这个版本”,请使用账本。 ### 合规性 / SLSA 证据 每次运行都会写入 `audit-report.json`(包含总体结论 + 每个 crate 和通道的每项发现)并将其作为 workflow artifact 上传 —— 这就是该依赖项变更已被审查的记录。 ## 在本地运行 需要 `rustup`/`cargo`、`rustfilt`(`cargo install rustfilt`)以及一个符号列举工具(GNU `nm`,或 `rustup component add llvm-tools` → `llvm-nm`,在 Windows 上会自动检测)。在 **Git Bash** 中: ``` bash test/run_local.sh # -> RESULT: 46 passed, 0 failed / ALL GREEN ``` 将演练所有五个通道、账本棘轮机制、配置抑制、设卡、Dependabot 建议以及证据报告 —— 完全离线运行,使用测试夹具和模拟的 crates.io / OSV 响应(外加一次真实的 crates.io 升级)。有关真实 PR 的检查清单,请参阅 [`TESTING.md`](TESTING.md)。 ## 能捕获和无法捕获的内容 **擅长捕获:** 开始直接调用 `std::net`/`process`/`fs` 的 crate;新增或修改的 **build script** / **proc-macro**(即使该 crate 无法作为 lib 构建时);新链接的**原生库**;依赖树中的**新 crates**;**发布者/仓库/撤回 (yank)** 状态的变更;新版本上的**已知安全公告**。 **遗漏 / 局限(静态分析固有的缺陷):** 通过从未在 crate 自身的 rlib 中实例化的泛型,或通过未更改的依赖项体现出的能力;运行时行为(它只读取表面接口,不进行沙盒隔离);无法独立构建的 crates(仅影响 symbol 通道 —— 其他通道仍然适用);网络通道需要网络连接,在离线状态下会优雅降级。可通过配置 + 账本调节以减少噪音。 ## 分发的最佳第一步 发布到 **GitHub Marketplace**(安全类别),标语为*“一个针对 Rust 依赖 PR 的 capability-creep 分拣卡点 —— 带有您可以用来阻断合并的审查棘轮。”* 编译时代码通道和签署放行棘轮机制,正是仅提供 symbol 和仅提供 advisory 的工具所缺乏的具体抓手。
标签:GitHub Action, Rust, XSS, 代码审查, 依赖审计, 可视化界面, 安全门禁, 文档安全, 漏洞情报, 网络流量审计