bigywater.tech
Rust · 166

依赖安全审计

依赖里的已知漏洞,编译器不会告诉你。RustSec 维护了公告数据库,cargo audit 拿它去对 Cargo.lock。这篇用故意固定的老版本依赖,把审计的输出、JSON、豁免、修复,以及 cargo deny 的另外几类规则逐个跑一遍。

2 + 2
cargo audit 报告的漏洞数 + 警告数
9.8
smallvec 1.6.0 公告的 CVSS 严重度(critical)
1279
本机拉到的 RustSec 公告数(漏洞库提交日期 2026-10-01)

被审计的项目

实测 · 本机执行输出
  Cargo.toml:
    [package]
    name = "au"
    version = "0.1.0"
    edition = "2024"
    
    [dependencies]
    smallvec = "=1.6.0"
    chrono = { version = "=0.4.19", default-features = false, features = ["clock"] }
    atty = "=0.2.14"
  cargo tree:
    au v0.1.0 (<实验目录>/proj/u166)
    ├── atty v0.2.14
    │   └── libc v0.2.189
    ├── chrono v0.4.19
    │   ├── libc v0.2.189
    │   ├── num-integer v0.1.47
    │   │   └── num-traits v0.2.19
    │   │       [build-dependencies]
    │   │       └── autocfg v1.5.1
    │   └── num-traits v0.2.19 (*)
    └── smallvec v1.6.0
     Downloading crates ...
      Downloaded num-traits v0.2.19
      Downloaded atty v0.2.14
    …(共 18 行)

依赖锁定见Cargo.lock,依赖解析见Cargo 依赖解析。

cargo audit

实测 · 本机执行输出
  退出码 1;耗时 2.1 秒
    Crate:     chrono
    Version:   0.4.19
    Title:     Potential segfault in `localtime_r` invocations
    Date:      2020-11-10
    ID:        RUSTSEC-2020-0159
    URL:       https://rustsec.org/advisories/RUSTSEC-2020-0159
    Solution:  Upgrade to >=0.4.20
    
    Crate:     smallvec
    Version:   1.6.0
    Title:     Buffer overflow in SmallVec::insert_many
    Date:      2021-01-08
    ID:        RUSTSEC-2021-0003
    URL:       https://rustsec.org/advisories/RUSTSEC-2021-0003
    Severity:  9.8 (critical)
    Solution:  Upgrade to >=0.6.14, <1.0.0 OR >=1.6.1
    
    Crate:     atty
    Version:   0.2.14
    Warning:   unmaintained
    Title:     `atty` is unmaintained
    Date:      2024-09-25
    ID:        RUSTSEC-2024-0375
    URL:       https://rustsec.org/advisories/RUSTSEC-2024-0375
    
    Crate:     atty
    Version:   0.2.14
    Warning:   unsound
    Title:     Potential unaligned read
    Date:      2021-07-04
    ID:        RUSTSEC-2021-0145
    URL:       https://rustsec.org/advisories/RUSTSEC-2021-0145
    
        Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
          Loaded 1279 security advisories (from <实验目录>/rustup_cargo/advisory-db)
        Updating crates.io index
        Scanning Cargo.lock for vulnerabilities (12 crate dependencies)
    error: 2 vulnerabilities found!
    warning: 2 allowed warnings found
  本地漏洞库最近一次提交: 2026-10-01T22:25:27+02:00 6de44551
  漏洞库里 crates/ 目录下的公告文件数:1259

离线与耗时

实测 · 本机执行输出
  cargo audit --no-fetch:退出码 1;耗时 0.1 秒

JSON 输出

实测 · 本机执行输出
  退出码 1;vulnerabilities.found=True,count=2
    RUSTSEC-2020-0159  chrono 0.4.19  patched=['>=0.4.20']  cvss=None
    RUSTSEC-2021-0003  smallvec 1.6.0  patched=['>=0.6.14, <1.0.0', '>=1.6.1']  cvss=CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
  warnings 分类: {'unmaintained': [('atty', 'RUSTSEC-2024-0375')], 'unsound': [('atty', 'RUSTSEC-2021-0145')]}
  lockfile 里的依赖数: 12 ;database.advisory-count: 1279

忽略与严格模式

实测 · 本机执行输出
  忽略那两个漏洞,退出码 0
    Crate:     atty
    Version:   0.2.14
    Warning:   unmaintained
    Title:     `atty` is unmaintained
    Date:      2024-09-25
    ID:        RUSTSEC-2024-0375
    URL:       https://rustsec.org/advisories/RUSTSEC-2024-0375
    
    Crate:     atty
    Version:   0.2.14
    Warning:   unsound
    Title:     Potential unaligned read
    Date:      2021-07-04
    ID:        RUSTSEC-2021-0145
    URL:       https://rustsec.org/advisories/RUSTSEC-2021-0145
    
          Loaded 1279 security advisories (from <实验目录>/rustup_cargo/advisory-db)
        Scanning Cargo.lock for vulnerabilities (12 crate dependencies)
    warning: 2 allowed warnings found
  再加 --deny warnings,退出码 1

修复

实测 · 本机执行输出
  升级后的 cargo tree:
    au v0.1.0 (<实验目录>/proj/u166)
    ├── chrono v0.4.45
    │   ├── iana-time-zone v0.1.65
    │   │   └── core-foundation-sys v0.8.7
    │   └── num-traits v0.2.19
    │       [build-dependencies]
    │       └── autocfg v1.5.1
    └── smallvec v1.16.2
     Downloading crates ...
      Downloaded smallvec v1.16.2
      Downloaded iana-time-zone v0.1.65
      Downloaded chrono v0.4.45
  cargo audit:退出码 0
          Loaded 1279 security advisories (from <实验目录>/rustup_cargo/advisory-db)
        Scanning Cargo.lock for vulnerabilities (39 crate dependencies)

只看版本,不看调用

实测 · 本机执行输出
  上面第二节里 main 只有 println!("hello"),smallvec 与 chrono 都不在 main 里使用;报告仍然出现 —— 审计依据的是 Cargo.lock 里「有没有这个版本」,不是调用图
  恢复旧依赖后再审计:退出码 1

cargo deny

实测 · 本机执行输出
  cargo deny init:退出码 0 
  deny.toml 的段落: ['graph', 'output', 'advisories', 'licenses', 'bans', 'sources']
  cargo deny check(默认模板):退出码 5;耗时 4.5 秒
    advisories FAILED, bans ok, licenses FAILED, sources ok
    error[rejected]: failed to satisfy license requirements
    warning[no-license-field]: license expression was not specified in manifest for crate 'au = 0.1.0'
    warning[unlicensed]: a valid license expression could not be retrieved for the crate
    error[unlicensed]: au = 0.1.0 is unlicensed
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[rejected]: failed to satisfy license requirements
    error[unsound]: Potential unaligned read
    error[unmaintained]: `atty` is unmaintained
    error[vulnerability]: Potential segfault in `localtime_r` invocations
    error[vulnerability]: Buffer overflow in SmallVec::insert_many
  自己写的 deny.toml(允许 MIT/Apache-2.0/Unicode-3.0 许可证;禁止未知来源):退出码 5
    advisories FAILED, bans ok, licenses FAILED, sources ok
    warning[no-license-field]: license expression was not specified in manifest for crate 'au = 0.1.0'
    warning[unlicensed]: a valid license expression could not be retrieved for the crate
    error[unlicensed]: au = 0.1.0 is unlicensed
    warning[license-not-encountered]: license was not encountered
    error[unsound]: Potential unaligned read
    error[unmaintained]: `atty` is unmaintained
    error[vulnerability]: Potential segfault in `localtime_r` invocations
    error[vulnerability]: Buffer overflow in SmallVec::insert_many
  只检查 licenses:退出码 4

放进 CI

实测 · 本机执行输出
  旧锁文件:cargo audit 退出码 1(CI 里这一步失败)  升级后:退出码 0(通过)

完整的持续集成流程见Rust 项目持续集成。

分步演示

cargo audit
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。nightly 工具链用 rustup 装在隔离目录(不影响 brew 的 rustc):rustc 1.101.0-nightly (21b707e3f 2026-09-30)、miri 0.1.0 (21b707e3f9 2026-09-30)。cargo-audit 0.22.2、cargo-deny 0.20.2(cargo install --locked,装在隔离目录);RustSec 漏洞库通过代理从 GitHub 拉取
    • 没有验证:漏洞库里更新的公告、cargo audit fix(自动改 Cargo.toml)、cargo deny 的 bans 规则(重复版本、wildcard、skip)在真实多版本冲突项目里的表现、私有 registry 与 git 依赖的来源规则、对 yanked 版本的检测
    • 本篇用的是固定在老版本的依赖,结果会随 RustSec 漏洞库的更新而变化
    京ICP备2026067502号-1京公网安备11010502063487号