SuperAPI AI 工具集

rust-security

安全与审计

查看项目

更新于 10-15 17:47

技能介绍

用途

本技能引导智能体掌握 Rust 安全实践,覆盖依赖审计、策略执行、RUSTSEC 公告数据库、FFI 内存安全模式,以及将模糊测试与 Miri 结合用于安全审查。

触发场景包括:如何检查 Rust 依赖中的 CVE、如何使用 cargo-audit、如何在 CI 中执行依赖策略、什么是 RUSTSEC 公告数据库、如何编写内存安全的 Rust FFI、如何对 Rust 库进行模糊测试以发现安全缺陷。

主要能力

1. cargo-audit — 漏洞扫描

安装:cargo install cargo-audit --locked

常用命令:

  • 扫描当前项目:cargo audit
  • 包含被忽略项的完整输出:cargo audit --deny warnings
  • 审计 lockfile(适合 CI):cargo audit --file Cargo.lock
  • JSON 输出用于 CI 集成:cargo audit --json | jq '.vulnerabilities.list[].advisory.id'

输出格式示例:

error[RUSTSEC-2023-0052]: Vulnerability in `vm-superio`
    Severity: low
       Title: MMIO Register Misuse
    Solution: upgrade to `>= 0.7.0`

2. cargo-deny — 策略执行

cargo-deny 不止于审计:它执行许可证策略、禁用特定 crate、检查来源,并校验重复依赖版本。

安装:cargo install cargo-deny --locked

初始化:cargo deny init

运行全部检查:cargo deny check

运行特定检查:cargo deny check advisories、cargo deny check licenses、cargo deny check bans、cargo deny check sources

deny.toml 配置示例:

[advisories]
vulnerability = "deny"      # Deny known vulnerabilities
unmaintained = "warn"       # Warn on unmaintained crates
yanked = "deny"             # Deny yanked versions

# Ignore specific advisories
ignore = [
    "RUSTSEC-2021-0145",    # known false positive for our usage
]

[licenses]
unlicensed = "deny"
allow = [
    "MIT", "Apache-2.0", "Apache-2.0 WITH LLVM-exception",
    "BSD-2-Clause", "BSD-3-Clause", "ISC", "Unicode-DFS-2016",
]
# Deny GPL for proprietary projects
deny = ["GPL-2.0", "GPL-3.0"]

[bans]
multiple-versions = "warn"  # Warn if same crate appears twice
wildcards = "deny"          # Deny wildcard dependencies

[[bans.deny]]
name = "openssl"            # Force rustls instead
wrappers = ["reqwest"]      # Allow if only required by these

[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-git = [
    "https://github.com/my-org/private-crate",
]

GitHub Actions CI 集成:

- name: Security audit
  run: |
    cargo install cargo-deny --locked
    cargo deny check

3. RUSTSEC 公告数据库

RUSTSEC 数据库位于 https://rustsec.org/,跟踪漏洞、无人维护的 crate 以及不健全代码。

从 CLI 浏览公告:

  • cargo audit --db ~/.cargo/advisory-db fetch
  • ls ~/.cargo/advisory-db/crates/
  • 查看特定公告:curl https://rustsec.org/advisories/RUSTSEC-2023-0001.json | jq .

常见类别:

  • type: vulnerability — 可利用的安全缺陷
  • type: unmaintained — 不再维护(供应链风险)
  • type: unsound — 安全 API 中已记录的不健全性
  • type: yanked — 已从 crates.io 撤回的 crate 版本

4. 内存安全的 FFI 模式

Rust/C 边界常见的不安全来源:

不安全模式(来自 C 的裸指针,无生命周期):

// UNSAFE pattern — raw pointer from C, no lifetime
extern "C" fn process_data(data: *const u8, len: usize) {
    // Don't do this — no bounds check, no lifetime guarantee
    let slice = unsafe { std::slice::from_raw_parts(data, len) };
}

安全模式(使用前先校验):

// SAFE pattern — validate before using
extern "C" fn process_data(data: *const u8, len: usize) -> i32 {
    // Validate pointer and length
    if data.is_null() || len == 0 || len > 1024 * 1024 {
        return -1;
    }
    // Safety: non-null, len validated, called from C with valid buffer
    let slice = unsafe { std::slice::from_raw_parts(data, len) };
    do_work(slice);
    0
}

对常见模式使用安全封装 crate:

use nix::unistd::read;   // safe POSIX wrappers
use windows::Win32::System::Memory::VirtualAlloc;  // safe Windows bindings

5. 模糊测试发现安全缺陷

cargo-fuzz(基于 libFuzzer):

  • 安装:cargo install cargo-fuzz
  • 初始化:cargo fuzz init
  • 添加目标:cargo fuzz add my_target

目标文件 fuzz/fuzz_targets/my_target.rs:

#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
    if let Ok(s) = std::str::from_utf8(data) {
        let _ = my_lib::parse(s);
    }
});

运行:

  • 长时间运行:cargo fuzz run my_target
  • 带 sanitizer 以覆盖安全场景:cargo fuzz run my_target -- -sanitizer=address
  • 复现崩溃:cargo fuzz run my_target artifacts/my_target/crash-xxxx

Honggfuzz(适合安全目标):

  • cargo install honggfuzz
  • cargo hfuzz run my_target

6. Miri 检查健全性

  • 安装 Miri:rustup +nightly component add miri
  • 在 Miri 下运行测试:cargo +nightly miri test
  • 检查 unsafe 代码中的 UB:
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-backtrace=full" \
  cargo +nightly miri test

Miri 可检测:

  • 释放后使用
  • 悬垂引用
  • 无效指针运算
  • 数据竞争(配合 -Zmiri-tree-borrows)
  • 未初始化内存读取

7. 供应链加固

  • 在应用程序(而非库)中固定 Cargo.lock;二进制项目始终提交 Cargo.lock
  • 校验校验和(cargo 已自动完成):cargo fetch --locked(若 Cargo.lock 不匹配则失败)
  • 审计所有依赖(含传递依赖):cargo tree 查看完整依赖树,cargo tree -d 显示重复版本
  • 使用 cargo-vet 对新依赖进行同行评审:cargo install cargo-vet,cargo vet 检查所有依赖是否已通过审查
  • 最小依赖原则:cargo machete 查找未使用的依赖

相关技能

  • skills/rust/rust-sanitizers-miri:Miri 与 sanitizer 细节
  • skills/runtimes/fuzzing:模糊测试策略与语料管理
  • skills/rust/rust-unsafe:unsafe 代码审计模式
  • skills/rust/cargo-workflows:Cargo.lock 与工作区管理