# Security And Vulnerability Management

> ______________________________________________________________________

- Skill: `majiayu000/security-and-vulnerability-management` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add majiayu000/security-and-vulnerability-management`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/security-and-vulnerability-management/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/majiayu000/security-and-vulnerability-management

---


______________________________________________________________________

## priority: critical

# Security & Vulnerability Management

**CVE disclosure · cargo-audit · cargo-deny · Fuzzing · Unsafe code review · Security testing**

## Vulnerability Management

- **cargo-audit**: Run on every commit and in CI; fail build on known vulnerabilities

  ```bash
  cargo audit
  cargo audit --deny warnings  # Fail on advisories
  ```

- **cargo-deny**: Detect vulnerable, unmaintained, and unlicensed dependencies

  ```bash
  cargo deny check advisories
  cargo deny check bans
  cargo deny check sources
  ```

- **CVE Disclosure Policy**:

  - Report to maintainers privately before public disclosure
  - Allow 90 days for patch before public CVE announcement
  - Document CVE in `SECURITY.md` with patch version and workarounds
  - Never commit exploits; reference by CVE ID and mitigation
  - Include timeline: discovery → disclosure → patch release

### Cargo.lock Management

```toml
# Cargo.toml
[dependencies]
serde = "=1.0.150"  # Pin critical deps to known safe versions
serde_json = "=1.0.89"

# Run lock file checks in CI
# .github/workflows/security.yml
- name: Check lock file
  run: cargo tree --locked  # Ensure lock matches Cargo.toml
```

## Fuzzing with cargo-fuzz

- **Setup**: `cargo install cargo-fuzz && cargo fuzz init`
- **Fuzz targets**: `fuzz/fuzz_targets/` directory; one target per public API surface
- **Continuous fuzzing**: Run in CI with timeout limits (e.g., 60 seconds per commit)
- **Crash reproduction**: Save failing inputs; add regression tests

### Fuzzing Example

```rust
// fuzz/fuzz_targets/parse_fuzzer.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
use my_crate::parse;

fuzz_target!(|data: &[u8]| {
    // Parse should never crash or panic on arbitrary input
    let _ = parse(data);
});
```

```bash
# Run fuzzing
cargo +nightly fuzz run parse_fuzzer -- -max_len=1024 -timeout=5

# Minimize failing input
cargo +nightly fuzz cmin parse_fuzzer
```

## Unsafe Code Review

- **SAFETY comments**: EVERY `unsafe` block MUST have a `// SAFETY:` comment explaining:

  1. What invariant is being relied upon
  1. Why calling code maintains that invariant
  1. What could go wrong if invariant is violated

- **Isolation**: Unsafe code in dedicated modules; public API must be safe

- **Review checklist**:

  - All pointers are valid (not null, not dangling)
  - Pointer dereferencing is properly aligned
  - No use-after-free (object still alive)
  - No double-free (only freed once)
  - No data races (proper synchronization)
  - Type safety maintained across FFI boundaries

### Unsafe Code Example

```rust
/// SAFETY: This function assumes the pointer points to valid, initialized memory
/// for at least `len` bytes. Caller MUST ensure pointer is:
/// - Non-null and properly aligned
/// - Pointing to valid, initialized T values
/// - Valid for reads of at least `len * sizeof(T)` bytes
/// - No aliasing mutable references exist to this data
unsafe fn copy_from_raw(ptr: *const u8, len: usize) -> Vec<u8> {
    std::slice::from_raw_parts(ptr, len).to_vec()
}

// Calling code MUST validate preconditions
let data = unsafe {
    // SAFETY: C function guarantees ptr is valid, len bytes
    copy_from_raw(c_buffer, buffer_len)
};
```

## Security Testing

- **No panics on untrusted input**: All public functions should return `Result`, never panic on bad input

- **Test adversarial inputs**:

  - Empty data
  - Maximum size data
  - Null/invalid pointers (for FFI)
  - Concurrency stress tests (data races)

- **Input validation**: Validate all untrusted input at boundaries (FFI, network, files)

- **Property-based testing**: Use `proptest` for fuzz-like testing in normal tests

### Security Test Example

```rust
#[cfg(test)]
mod security_tests {
    use proptest::proptest;

    #[test]
    fn parse_never_panics_on_arbitrary_input() {
        // Test with random bytes
        for _ in 0..1000 {
            let random_bytes = rand::random::<Vec<u8>>();
            let result = my_crate::parse(&random_bytes);
            // Should return Err, never panic
            assert!(result.is_ok() || result.is_err());
        }
    }

    #[test]
    fn handles_max_size_input() {
        let huge_input = vec![0u8; 1024 * 1024 * 100];  // 100MB
        let result = my_crate::parse(&huge_input);
        assert!(result.is_ok() || result.is_err());  // Never panic
    }

    proptest! {
        #[test]
        fn parse_property_never_panics(input in ".*") {
            let _ = my_crate::parse(input.as_bytes());
        }
    }
}
```

## Dependency Management

- **Minimize dependencies**: Each dependency is a potential vulnerability surface
- **Evaluate before adding**: Check security history, maintenance status, license
- **Keep updated**: Regular `cargo update` but within version constraints
- **Audit on CI**: Every PR should pass `cargo audit` and `cargo deny`

### Deny Configuration

```toml
# deny.toml
[advisories]
vulnerability = "deny"
unmaintained = "warn"
yanked = "warn"
notice = "warn"
ignore = []

[bans]
multiple-versions = "warn"
wildcards = "warn"
allow = []
deny = [
    { name = "openssl", version = "<0.10" },
    { name = "parking_lot", version = "*" }  # Use std instead
]

[sources]
unknown-registry = "warn"
unknown-git = "warn"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
```

## Anti-Patterns

- **No SAFETY comments**: Unsafe code without explanation is unreviewable and unmaintainable
- **Unsafe in public API**: Safe wrapper should be enforced at public boundary
- **Ignoring cargo-audit warnings**: Known vulns should block builds immediately
- **Panicking on untrusted input**: `unwrap()` on parsed/network data will crash in production
- **No fuzzing of parsers**: Parsers are attack surface; fuzzing essential
- **Mixing unsafe and concurrency**: Unsafe + threading = subtle data races; minimize overlap
- **Outdated dependencies**: Stale deps accumulate vulns; regular updates required
- **No bounds checking on FFI pointers**: Dereferencing unchecked FFI pointers is UB

## Security Checklist for Release

- [ ] `cargo audit` passes (no known vulns)
- [ ] `cargo deny check` passes (licenses, sources)
- [ ] All unsafe blocks have SAFETY comments
- [ ] Fuzzing targets pass (no crashes)
- [ ] `cargo test --release` passes (including security tests)
- [ ] No panics on arbitrary input
- [ ] Dependencies are reviewed for security
- [ ] SECURITY.md updated with any CVE fixes

