I'm trying to enumerate all ways in which using Rust and Cargo dependencies could be dangerous, i.e. lead to execution of malicious code.
We often have discussions about improving security of dependencies, but different people have different risks in mind. The topic is very broad, and no single security solution can solve all the problems.
I think for the sake of such discussions it would be good to have a shared list of all known dangers, so we don't talk past each other: "We need X! But it doesn't prevent Y!". If someone proposes a new solution like "developers should stop viruses by washing their hands!" or "crates-io should be a blockchain!" we could systematically evaluate which attacks that would stop, and which attacks would be better served by a different solution.
My first draft of possible horror scenarios is below. Can you think of other situations that aren't on the list?
I'm interested in a very broad view: deliberate attacks as well as accidental vulnerabilities, from attacks by bored kids to well-motivated criminal enterprises or state agencies.
I don't want to discuss any particular solutions here. If you have a fantastic solution in mind, please don't propose it here. Only list the security issues it solves.
-
crates.io infrastructure hacked
- main API servers breached β attacker may bypass authentication and publish any crate as any user
- XSS vulnerability on crates.io β attacker may automatically accept invitations or steal login tokens of site's visitors
- SQL injection β might leak GitHub auth tokens (fortunately, the API tokens are hashed quite well)
- index repository hacked β attacker can change checksums, and replace
config.json
to redirect tarballs to an attacker-controlled mirror
- rustup infrastructure hacked β attacker can distribute malicious version of Rust itself
- developer's own machine compromised
- in case it's leaking files, but no arbitrary code execution β e.g. path traversal vulnerability may allow attacker to read sensitive user-owned files
- arbitrary code execution β attacker can do whatever they want, including hijacking
cargo publish
orgit push
commands
- developer's own auth token leaked β attacker gets hold of auth token that allows publishing crates
- developer's GitHub account hacked β attacker takes control of a dev's account, e.g. by guessing password, using a leaked token or cookie, vulnerability in GitHub itself, etc.
- when the developer can manage GitHub teams that own crates β attacker can add themselves to teams
- when the hack enables logging in to crates.io β attacker may make new API tokens, send ownership invites to themselves, kick other owners out
- attacker taking control of CI that is set up to publish crates β attacker may exploit CI configuration (e.g. if it gives secrets to code in pull requests, or runs code of a malicious GitHub Action) or hijack CI account
- reputable crate that is dependency of other crates under new management
- legitimate crate given/sold to someone who turns out to be malicious
- dispute between co-owners ends in an ugly fight β e.g. a disgruntled co-owners may decide to sabotage or destroy the project
- bad actor publishing intentionally malicious crate β no exploit, just hoping someone will find it and install it voluntarily
- with obvious malware β in case the code attacks immediately and directly
- with obfuscated backdoor/hidden malware - uses obfuscated code to hide its intentions, public repo may contain different code
- delayed attack β start by publishing a clean, useful crate, and add malware only after victims start using it
- typosquatting, bitsquatting, homographs, confusable names β malicious crate published under a name that is confusingly similar to other, legitimate crates
- malicious dependency attacks via:
- build.rs
- proc-macro
- regular macro
- library function
- static constructors or unmangled symbol overrides that run automatically, possibly before
main
- embedding secrets via
include_str!("/etc/passwd")
orenv!("SECRET_TOKEN")
and relying on the executable being published by its owner
- exploitable vulnerability in a legitimate crate
- by accident, written by crate authors
- actually-unsafe use of
unsafe
features - other mistake, such as weak crypto, trusting unchecked user inputs, logic errors, default passwords
- build.rs script downloads source code insecurely (e.g. unencrypted, or remote server is hacked)
- actually-unsafe use of
- intentional bug that slipped through a pull request
- due to miscompilation β e.g a soundness bug in Rust, or an invalid optimization in LLVM
- due to a vulnerabilities in the operating system or non-Rust dependencies
- by accident, written by crate authors
- machine on which you fetch dependencies has broken TLS (e.g. because of a buggy corporate MITM proxy or because you're the #1 enemy of a state spy agency)