rust-security

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Rust Security

Rust安全

Purpose

用途

Guide agents through Rust security practices: dependency auditing with cargo-audit, policy enforcement with cargo-deny, RUSTSEC advisory database, memory-safe patterns for FFI, and combining fuzzing with Miri for security review.
指导Agent掌握Rust安全实践:使用cargo-audit进行依赖审计、通过cargo-deny执行策略管控、RUSTSEC漏洞咨询数据库、面向FFI的内存安全模式,以及将模糊测试与Miri结合用于安全评审。

Triggers

触发场景

  • "How do I check my Rust dependencies for CVEs?"
  • "How do I use cargo-audit?"
  • "How do I enforce dependency policies in CI?"
  • "What's the RUSTSEC advisory database?"
  • "How do I write memory-safe FFI in Rust?"
  • "How do I fuzz-test my Rust library for security bugs?"
  • "如何检查我的Rust依赖是否存在CVE漏洞?"
  • "如何使用cargo-audit?"
  • "如何在CI中执行依赖策略?"
  • "什么是RUSTSEC咨询数据库?"
  • "如何在Rust中编写内存安全的FFI?"
  • "如何对我的Rust库进行模糊测试以发现安全漏洞?"

Workflow

工作流程

1. cargo-audit — vulnerability scanning

1. cargo-audit — 漏洞扫描

bash
undefined
bash
undefined

Install

安装

cargo install cargo-audit --locked
cargo install cargo-audit --locked

Scan current project

扫描当前项目

cargo audit
cargo audit

Full output including ignored

包含忽略项的完整输出

cargo audit --deny warnings
cargo audit --deny warnings

Audit the lockfile (CI-friendly)

审计锁文件(适合CI环境)

cargo audit --file Cargo.lock
cargo audit --file Cargo.lock

JSON output for CI integration

生成JSON输出用于CI集成

cargo audit --json | jq '.vulnerabilities.list[].advisory.id'

Output format:
error[RUSTSEC-2023-0052]: Vulnerability in
vm-superio
Severity: low Title: MMIO Register Misuse Solution: upgrade to
>= 0.7.0
undefined
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
undefined

2. cargo-deny — policy enforcement

2. cargo-deny — 策略执行

cargo-deny goes beyond audit: it enforces license policies, bans specific crates, checks source origins, and validates duplicate dependency versions.
bash
cargo install cargo-deny --locked
cargo-deny的功能超越审计:它可执行许可证策略、禁用特定 crate、检查源来源,并验证重复依赖版本。
bash
cargo install cargo-deny --locked

Initialize deny.toml

初始化deny.toml

cargo deny init
cargo deny init

Run all checks

运行所有检查

cargo deny check
cargo deny check

Run specific check

运行特定检查

cargo deny check advisories cargo deny check licenses cargo deny check bans cargo deny check sources

`deny.toml` configuration:

```toml
[advisories]
vulnerability = "deny"      # Deny known vulnerabilities
unmaintained = "warn"       # Warn on unmaintained crates
yanked = "deny"             # Deny yanked versions
cargo deny check advisories cargo deny check licenses cargo deny check bans cargo deny check sources

`deny.toml` 配置:

```toml
[advisories]
vulnerability = "deny"      # 拒绝已知漏洞
unmaintained = "warn"       # 对未维护的 crate 发出警告
yanked = "deny"             # 拒绝已撤回的版本

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", ]
ignore = [ "RUSTSEC-2021-0145", # 我们的使用场景中已知的误报 ]
[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

针对专有项目拒绝GPL许可证

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 integration:

```yaml
- name: Security audit
  run: |
    cargo install cargo-deny --locked
    cargo deny check
deny = ["GPL-2.0", "GPL-3.0"]
[bans] multiple-versions = "warn" # 若同一 crate 出现多次则发出警告 wildcards = "deny" # 拒绝通配符依赖
[[bans.deny]] name = "openssl" # 强制使用rustls替代 wrappers = ["reqwest"] # 仅允许由这些依赖引入时使用
[sources] unknown-registry = "deny" unknown-git = "deny" allow-git = [ "https://github.com/my-org/private-crate", ]

GitHub Actions CI集成:

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

3. RUSTSEC advisory database

3. RUSTSEC咨询数据库

The RUSTSEC database at https://rustsec.org/ tracks vulnerabilities, unmaintained crates, and unsound code.
bash
undefined
bash
undefined

Browse advisories from CLI

从CLI浏览咨询项

cargo audit --db ~/.cargo/advisory-db fetch ls ~/.cargo/advisory-db/crates/
cargo audit --db ~/.cargo/advisory-db fetch ls ~/.cargo/advisory-db/crates/

Check a specific advisory

查看特定咨询项

Common categories

常见分类

type: vulnerability — exploitable security bug

type: vulnerability — 可被利用的安全漏洞

type: unmaintained — no longer maintained (supply chain risk)

type: unmaintained — 不再维护(供应链风险)

type: unsound — documented unsoundness in safe API

type: unsound — 安全API中存在文档说明的不安全性

type: yanked — crate version yanked from crates.io

type: yanked — crate版本已从crates.io撤回

undefined
undefined

4. Memory-safe FFI patterns

4. 内存安全的FFI模式

Common sources of unsafety at the Rust/C boundary:
rust
// 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
}

// Use safe wrapper crates for common patterns
use nix::unistd::read;   // safe POSIX wrappers
use windows::Win32::System::Memory::VirtualAlloc;  // safe Windows bindings
Rust/C边界处常见的不安全来源:
rust
// 不安全模式 — 来自C的原始指针,无生命周期
extern "C" fn process_data(data: *const u8, len: usize) {
    // 不要这样做 — 无边界检查,无生命周期保证
    let slice = unsafe { std::slice::from_raw_parts(data, len) };
}

// 安全模式 — 使用前先验证
extern "C" fn process_data(data: *const u8, len: usize) -> i32 {
    // 验证指针和长度
    if data.is_null() || len == 0 || len > 1024 * 1024 {
        return -1;
    }
    // 安全性:非空指针,长度已验证,由C传入有效缓冲区
    let slice = unsafe { std::slice::from_raw_parts(data, len) };
    do_work(slice);
    0
}

// 针对常见模式使用安全封装 crate
use nix::unistd::read;   // 安全的POSIX封装
use windows::Win32::System::Memory::VirtualAlloc;  // 安全的Windows绑定

5. Fuzzing for security bugs

5. 针对安全漏洞的模糊测试

bash
undefined
bash
undefined

cargo-fuzz — libFuzzer-based

cargo-fuzz — 基于libFuzzer

cargo install cargo-fuzz
cargo install cargo-fuzz

Initialize

初始化

cargo fuzz init cargo fuzz add my_target
cargo fuzz init cargo fuzz add my_target

fuzz/fuzz_targets/my_target.rs

fuzz/fuzz_targets/my_target.rs

#![no_main]

#![no_main]

use libfuzzer_sys::fuzz_target;

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {

fuzz_target!(|data: &[u8]| {

if let Ok(s) = std::str::from_utf8(data) {

if let Ok(s) = std::str::from_utf8(data) {

let _ = my_lib::parse(s);

let _ = my_lib::parse(s);

}

}

});

});

Run fuzzing (long-running)

运行模糊测试(长期运行)

cargo fuzz run my_target
cargo fuzz run my_target

With sanitizers for security coverage

结合 sanitizer 提升安全覆盖范围

cargo fuzz run my_target -- -sanitizer=address
cargo fuzz run my_target -- -sanitizer=address

Reproduce a crash

复现崩溃

cargo fuzz run my_target artifacts/my_target/crash-xxxx

```bash
cargo fuzz run my_target artifacts/my_target/crash-xxxx

```bash

Honggfuzz — good for security targets

Honggfuzz — 适合安全目标

cargo install honggfuzz cargo hfuzz run my_target
undefined
cargo install honggfuzz cargo hfuzz run my_target
undefined

6. Miri for soundness

6. 使用Miri检查安全性

bash
undefined
bash
undefined

Install Miri

安装Miri

rustup +nightly component add miri
rustup +nightly component add miri

Run tests under Miri

在Miri下运行测试

cargo +nightly miri test
cargo +nightly miri test

Check for UB in unsafe code

检查不安全代码中的未定义行为

MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-backtrace=full"
cargo +nightly miri test
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-backtrace=full"
cargo +nightly miri test

Miri detects:

Miri可检测:

- Use-after-free

- 使用后释放(Use-after-free)

- Dangling references

- 悬空引用

- Invalid pointer arithmetic

- 无效指针运算

- Data races (with -Zmiri-tree-borrows)

- 数据竞争(配合-Zmiri-tree-borrows)

- Uninitialized memory reads

- 未初始化内存读取

undefined
undefined

7. Supply chain hardening

7. 供应链加固

bash
undefined
bash
undefined

Pin Cargo.lock in applications (not libraries)

在应用中固定Cargo.lock(库不适用)

Always commit Cargo.lock for binaries

始终为二进制文件提交Cargo.lock

Verify checksums (cargo already does this)

验证校验和(cargo已默认执行)

cargo fetch --locked # fails if Cargo.lock doesn't match
cargo fetch --locked # 若Cargo.lock不匹配则失败

Audit all dependencies including transitive

审计所有依赖,包括传递依赖

cargo tree # view full dependency tree cargo tree -d # show duplicate versions
cargo tree # 查看完整依赖树 cargo tree -d # 显示重复版本

Use cargo-vet for peer review of new deps

使用cargo-vet对新依赖进行同行评审

cargo install cargo-vet cargo vet # check all deps have been vetted
cargo install cargo-vet cargo vet # 检查所有依赖是否已通过评审

Minimal dependency principle

最小依赖原则

cargo machete # finds unused dependencies
undefined
cargo machete # 查找未使用的依赖
undefined

Related skills

相关技能

  • Use
    skills/rust/rust-sanitizers-miri
    for Miri and sanitizer details
  • Use
    skills/runtimes/fuzzing
    for fuzzing strategy and corpus management
  • Use
    skills/rust/rust-unsafe
    for unsafe code audit patterns
  • Use
    skills/rust/cargo-workflows
    for Cargo.lock and workspace management
  • 使用
    skills/rust/rust-sanitizers-miri
    获取Miri和sanitizer的详细信息
  • 使用
    skills/runtimes/fuzzing
    获取模糊测试策略和语料库管理相关内容
  • 使用
    skills/rust/rust-unsafe
    获取不安全代码审计模式
  • 使用
    skills/rust/cargo-workflows
    获取Cargo.lock和工作区管理相关内容