Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

cargo-frisk

Secret scanners check what git tracks. cargo frisk checks what cargo ships — and those are not the same files.

cargo package includes untracked-but-not-ignored files by design. A stray .env, a credentials.toml, a .pem you copied in to debug something — none of them are in git, so none of them are visible to a scanner that reads your repository. All of them go into the tarball, and the tarball is what lands on crates.io forever.

cargo frisk diffs the packaged .crate against git ls-files, then annotates the difference with secret-detection rules.

$ cargo frisk

frisk my-crate v0.3.1  14 files, 48.2 KB

  shipped, not tracked by git (1)
    .env                                             412 B

  shipped and tracked (12)
    (pass --verbose for the full listing)

  generated by cargo: Cargo.toml.orig, .cargo_vcs_info.json

  findings (3)
    critical shipped-not-tracked  .env
      packaged but not tracked by git, and the name indicates credentials
    critical env-file             .env
      environment file packaged into the crate
    critical aws-access-key-id    .env:1
      AWS access key ID
      AKIA************ (20 chars)

  3 finding(s): 3 critical  ·  fail-on = critical  ·  FAIL

Install

cargo install cargo-frisk

Or grab a prebuilt binary — no Rust toolchain, no compile:

cargo binstall cargo-frisk

Then, from any package:

cargo frisk

That is the whole setup. Nothing to configure.

What it checks

The diff — the product.

BucketMeaning
shipped, not trackedIn the tarball, not in git. The dangerous one, reported first.
tracked, not shippedIn git, not in the tarball. Usually intentional; occasionally an include list that drops a source file and ships a crate that will not build.
shipped and trackedThe boring, expected majority.

Files cargo synthesises (Cargo.toml.orig, .cargo_vcs_info.json, Cargo.lock) are listed separately rather than counted as untracked noise. Any file over 10% of the package size is called out.

The annotation — content and path rules over the packaged files. Provider tokens, private keys, .env files, credentials.toml, editor backups. Patterns are adapted from gitleaks (MIT; see NOTICE) plus rules specific to Cargo packaging.

Exit codes

Distinct, so CI can tell "found something" from "the tool broke":

CodeMeaning
0nothing unexpected
1findings at or above the fail threshold
2tool error — cargo package failed, malformed archive, bad config

False positives

Roughly two thirds of naive secret-scanner hits are test data or placeholders. Four mitigations, all on by default:

  1. fail-on = "critical". Everything below that reports without failing.

  2. Entropy gate. Generic patterns below ~3.5 bits/char are downgraded. password = "xxxxxxxxxxxxxxxx" will not fail your build.

  3. Path context. Hits under tests/, fixtures/, examples/ and friends drop one severity level — still reported, no longer blocking.

  4. Inline suppression. Put this on or above the offending line:

    // frisk:allow(aws-access-key-id)
    const EXAMPLE_KEY: &str = "AKIAIOSFODNN7EXAMPLE";

    frisk:allow(*) allows everything on that line. The comment marker does not matter — #, //, -- and anything else all work.

Findings are always reported even when downgraded. Nothing is silently dropped: files too large to scan or detected as binary are listed under not scanned rather than quietly skipped.

Configuration

In Cargo.toml, not a dotfile:

[package.metadata.frisk]
fail-on = "critical"                  # low | medium | high | critical | none
ignore-paths = ["tests/fixtures/**"]
ignore-rules = ["backup-file"]
max-file-size = 5242880               # per-file scan cap, bytes

[workspace.metadata.frisk] works too: it is the base that package-level keys override, and the list-valued keys accumulate across both.

CI

GitHub Actions

jobs:
  frisk:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write   # required by upload-sarif
    steps:
      - uses: actions/checkout@v5
      - uses: HaidarJbeily7/cargo-frisk@v1
        with:
          upload-sarif: true

Findings appear inline on the PR diff via GitHub Code Scanning. See action.yml for every input.

security-events: write is not optional when upload-sarif: true. A composite action cannot grant itself permissions, so without it the upload fails with Resource not accessible by integration. Drop the block entirely if you only want the human report and the exit code.

Pull requests from forks always receive a read-only token, whatever the workflow declares. The action detects this and skips the upload with a notice rather than failing the job.

pre-commit

repos:
  - repo: https://github.com/HaidarJbeily7/cargo-frisk
    rev: v0.1.0
    hooks:
      - id: cargo-frisk

Anything else

cargo frisk --sarif -o frisk.sarif
cargo frisk --json | jq '.packages[].findings[]'

Usage

cargo frisk [OPTIONS]

  --manifest-path <PATH>     Path to Cargo.toml
  -p, --package <NAME>       Frisk only this package (repeatable)
      --workspace            Frisk every workspace member
      --fail-on <SEVERITY>   low | medium | high | critical | none
      --format <FORMAT>      human | json | sarif
      --json                 Shorthand for --format json
      --sarif                Shorthand for --format sarif
  -o, --output <PATH>        Write the report to a file
      --no-scan              Report the diff only; skip content rules
      --gitleaks-config <P>  Load extra rules from a gitleaks-format TOML
      --ignore-rule <ID>     Disable a rule (repeatable)
      --ignore-path <GLOB>   Ignore findings under a glob (repeatable)
      --max-file-size <N>    Per-file scan cap in bytes
      --color <WHEN>         auto | always | never
  -v, --verbose              List every packaged file

--gitleaks-config accepts the upstream gitleaks.toml if you want all ~150 rules. Imported rules default to high — below the default gate — because we have not calibrated them.

What it deliberately does not do

  • It is not a secret-detection engine. gitleaks owns that problem. We consume its ruleset.
  • It does not reimplement Cargo's packaging logic. include/exclude/ .gitignore resolution is subtle, and a file set that diverged from the real upload would make this tool actively misleading. It always shells out to cargo package --no-verify --allow-dirty.
  • It does not scan git history. That is gitleaks' git mode.
  • It does not extract the tarball to disk. Writing a suspected secret to a new location is not something a security tool should do. Everything is streamed in memory.
  • It does not fix anything. Report and exit. Fixing is your job.

Library

lib.rs is public from v0.1:

use cargo_frisk::{run, Options};

let outcome = run(&Options::default())?;
for finding in outcome.findings() {
    println!("{} {} {}", finding.severity, finding.rule, finding.path);
}
# Ok::<(), anyhow::Error>(())

Development

MSRV is 1.85. rust-toolchain.toml pins the repo to stable.

cargo test
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo run -- frisk        # dogfood

Fixtures live in tests/fixtures/. Every "secret" in them is AWS's own documentation example: structurally valid enough to match, obviously fake enough that nobody panics.

Licence

MIT OR Apache-2.0, at your option. Vendored gitleaks patterns are MIT; see NOTICE.

关于 About

No description, website, or topics provided.

语言 Languages

Rust100.0%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
8
Total Commits
峰值: 8次/周
Less
More

核心贡献者 Contributors