Cargo Guard
Cargo build script allowlist.
Just cargo build, no wrappers needed.
Setup
1. Install Cargo Guard
# or
2. Configure Cargo
You have 2 options:
- Workspace approved builds (that can be committed to version control)
- Global approved builds (runs allow list on all workspaces)
To setup your project add the following to .cargo/config.toml in your project's workspace root:
[]
= true
= true
[]
= "cargo-guard"
To setup cargo guard globally add the following to your ~/.cargo/config.toml
[]
= true
= true
[]
= "cargo-guard"
[]
= { = ".cargo/approved-builds.toml", = true }
This configuration will tell Cargo to build your projects will cargo-guard as middleware between your Cargo and your build scripts. You will get an error if an unapproved build script tries to run.
Usage
Create approved-builds.toml in the workspace root.
Example:
[]
= "0.9.12"
It is recommended to use cargo guard review to automate this process.
Approval Syntax
[]
# Allow a single version
= "0.9.12"
# Allow all build scripts that match a fingerprint of the build script (not tied to single package version)
# The format is {build.rs hash}+{metadata}#{package version}
#
# The build.rs hash is the sha256 hash of the build script source file.
#
# Metadata here means anything that can influence build script that is not in the build.rs.
# This can include files included with env!() / include!(), build-dependencies, etc
#
# The `#{version}` is only a hint for `cargo guard review` to give better diffs in the UI.
# It does not pin to a specific version
= "f7609b919173e7121493266d0f89db724a1e47bb105ebd05397f869639603eec+61d8c10f3feb6de7#1.1.5"
# Allow multiple versions
= ["1.0.0", "1.2.0"]
# Allow multiple version and fingeprints mixed
= ["1.0.0", "f7609b919173e7121493266d0f89db724a1e47bb105ebd05397f869639603eec+61d8c10f3feb6de7#1.1.5"]
# Allow all version from this crate
= "approved"
Security
Regarding the security of these options, they all come with trades offs. Pinning to a single version is the most secure, but the most demanding in terms of maintenance. Everytime you update a dependency (including transitively) that has a build script, you must re-review and approve it even if it has not changed. This can to reviewers rubber stamping approvals due to alarm fatigue.
On the other end of the spectrum is "approved" which blanket approves the build scripts for a given
crate regardless of the version. This is the least secure and will not protect you if an attack takes control
of a crate with an existing build script and adds malicious code to it.
The fingerprint is meant to serve as a middleground between version pinning and blanket approvals by taking a fingerprint of a build script and only requiring a re-approval if it has changed. The fingerprint attempts to track the most common attack vectors for build.rs attacks but does not guarantee to capture everything.
Motivations
The goal of this project is to reduce the risk of a malious build script harming the Rust ecosystem. Build scripts are a known attack vector in the Rust supply chain and it not thoeritical. This project is an initial attempt at this problem taking inspiration from npm/pnpm's allow scripts feature. Long term, Cargo itself should probably handle this in a first class way. (see cargo#13681)
Limitations
- Requires nightly Rust to use
host.runner - Does not handle proc-macros
- The fingerprint format is currently not guaranteed to be stable across versions while the project is still young