TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Backdooring Rust crates for fun and profit

362 pointsby cjgover 3 years ago

28 comments

PragmaticPulpover 3 years ago
I use “cargo … —-locked” to install things using the dependencies from the Cargo.lock file, which includes specific commit hashes for dependencies. Avoids things like the 0.0.1 problem or even replaced crates. Need to be careful to watch for actual security updates, though.<p>I really wish crates.io would have at least launched with a name spacing feature. This wouldn’t solve every spoofing or typosquatting issue, but it would go a long way toward improving the situation.<p>There’s a separate issue of crates.io squatting. One person famously registered hundreds (or thousands? Tens of thousands) of common words as crate names on crates.io and has been squatting them ever since. Those names are effectively unavailable for use but also completely useless because they don’t contain anything.<p>It’s also becoming a huge problem for abandoned crates. New forks have to choose a completely different, less intuitive name because they can’t just namespace their alternative. As old crates get abandoned, this leads to weird situations where the newest, best maintained crate has the least obvious crate name. It takes work to find the good crate some times because the best named crates might just be the oldest, most abandoned ones
评论 #29267463 未加载
评论 #29266885 未加载
评论 #29266604 未加载
评论 #29267016 未加载
评论 #29266765 未加载
评论 #29266758 未加载
评论 #29274251 未加载
dathinabover 3 years ago
&gt; crates.io matches the code on GitHub,<p>There is no tight coupling between GitHub and cargo&#x2F;crates.io (sure it uses GitHub internally but that is an implementation detail).<p>But not only has it no tight coupling with GitHub it also doesn&#x27;t require you to use git, you can use whatever version control you want and at worse you don&#x27;t get support for &quot;detect dirty repository&quot;.<p>Similar git tags are fundamentally unreliable as you can always &quot;move&quot; some to any arbitrary commit.<p>So IMHO the problem here is relying on code you didn&#x27;t got from github which might not even use git to match a arbitrary tag on something on github which might not even be from the same author (but e.g. a mirror on GitHub from whatever VC the author uses).<p>But uploads to crates.io are immutable and are source code uploads, so you can just review them.<p>In general (independent of cargo) <i>do review the code you use</i> not some code you got form somewhere else which you hope&#x2F;believe is the same.
评论 #29267194 未加载
评论 #29266899 未加载
babyover 3 years ago
That&#x27;s why I started <a href="https:&#x2F;&#x2F;github.com&#x2F;mimoo&#x2F;cargo-dephell" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;mimoo&#x2F;cargo-dephell</a> and <a href="https:&#x2F;&#x2F;github.com&#x2F;diem&#x2F;whackadep" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;diem&#x2F;whackadep</a> btw, to try to get a sense of the risk in our Rust dependencies. Whackadep runs a a webserver that updates periodically and shows you what&#x27;s up with your dependencies. If there&#x27;s a new update, the idea is to estimate a sense of urgency (are we lagging behind? Is it a major version change? Is there a RUSTSEC advisory?) and a sense of risk. For example, it&#x27;ll tell you if a new dependency version touches a `build.rs` file. I wanted to add more rules, like the ones mentioned in the article, but never had the time to do it.
Diggseyover 3 years ago
There&#x27;s going to be a risk to running someone else&#x27;s code. There are two factors here:<p>1) Do I trust the code I think I&#x27;m running. 2) Am I actually running the code I think I&#x27;m running.<p>With (1) there&#x27;s not really any way around it: someone or something has to review the code in some way.<p>Even the suggestion to have a larger standard library doesn&#x27;t <i>really</i> address it: with a larger standard library the rust project needs more maintainers, and it might just get easier to get vulnerabilities into the standard library.<p>Someone could build a tool that automatically scans crates uploaded to crates.io. It could look for suspicious code patterns, or could simply figure out what side-effects a crate might have, based on what standard library functions it calls, and then provide that information to you. For example, if I&#x27;m looking for a SHA256 crate, and I notice that the crate uses the filesystem, then I might be suspicious.<p>With (2) there are some easier options, such as making it easier to download or browse the contents of a crate directly from crates.io, or have a tool to show the full dependency source diff after a `cargo update`. For initially installing the crate, the number of downloads is a pretty good indicator of &quot;is this really the crate I meant?&quot;.
评论 #29268035 未加载
pdimitarover 3 years ago
There&#x27;s zero backdooring involved anywhere in this article. His most convincing argument seems to be &quot;if your account as a package maintainer is hijacked then bad things could happen&quot; -- well yeah, thanks for the insight Sherlock.<p>I&#x27;d be genuinely excited to read objective and deeper analyses of the Rust ecosystem in which I am looking to invest myself further. I want to know what exactly I am getting involved with so I&#x27;d welcome any good criticisms of it.<p>But not click-baity articles with almost zero substance inside. He&#x27;s basically repeating old lists of risks of human error.
评论 #29273630 未加载
jynelsonover 3 years ago
&gt; While it’s possible to audit the code of a crate on <a href="https:&#x2F;&#x2F;docs.rs" rel="nofollow">https:&#x2F;&#x2F;docs.rs</a> on clicking on a [src] button, it turns that I couldn’t find a way to inspect build.rs files. Thus, combined with a malicious update, it’s the almost perfect backdoor.<p>Docs.rs has its own source view on &#x2F;crate that&#x27;s separate from rustdoc&#x27;s. For example, you can see the build.rs for boring-sys on `<a href="https:&#x2F;&#x2F;docs.rs&#x2F;crate&#x2F;boring-sys&#x2F;1.1.1&#x2F;source&#x2F;build.rs" rel="nofollow">https:&#x2F;&#x2F;docs.rs&#x2F;crate&#x2F;boring-sys&#x2F;1.1.1&#x2F;source&#x2F;build.rs</a>`.
评论 #29269286 未加载
thorumover 3 years ago
I’m increasingly fatalistic about computer security. It seems like your options are carefully auditing all dependencies (difficult and maybe impossible if the dependencies are highly technical or the malicious code is sufficiently subtle or obfuscated) every time you update, not updating at all (which leaves you vulnerable to all the bugs and other security issues in the version you choose to pin), or not using dependencies at all (by spending months or years totally rewriting the libraries and tools you need, and of course your own code will have bugs too).<p>Fixing the points addressed in this article helps by making it harder to slip these backdoors in, but will never be foolproof unless every single library has a maintainer with the skills to detect subtle bugs and security issues, who audits every line of code.<p>Even then the marketplace for unreported zero day vulnerabilities means that there are probably undiscovered vulnerabilities somewhere in your dependencies (or in the code for your IDE or OS or Spotify app or mouse driver...) that can be exploited by someone.<p>I’m reminded of the Commonwealth series by Peter Hamilton, in which the invading aliens have no machines, and quickly discover that ours are full of bugs that can be exploited to turn against us. I don’t know what the solution is. Sandboxing your development in a codespace like Gitpod is a big improvement for sure, but even in Gitpod a lot of people import credentials and environment variables that can be stolen. (And what dependencies is Gitpod itself running?)
评论 #29269875 未加载
评论 #29269651 未加载
评论 #29269945 未加载
评论 #29269569 未加载
评论 #29269537 未加载
评论 #29271961 未加载
评论 #29270892 未加载
rectangover 3 years ago
Is there a way to buy into PGP identity-based controls for crates.io packages? To say, &quot;I trust the keys in this whitelist, so trust packages signed by those keys.&quot;<p>&gt; <i>Thirdly, using cloud developer environments such as GitHub Codespaces or Gitpod. By working in sandboxed environments for each project, one can significantly reduce the impact of a compromise.</i><p>That&#x27;s appealing but expensive. I wish I could effectively sandbox a local developer machine. External boot drives, maybe?
评论 #29266161 未加载
jrochkind1over 3 years ago
Most of these are common to other platform packaging systems, and I&#x27;m not sure I&#x27;ve seen any especially interesting solutions to them.<p>The macro-based ones are rust-specific and seem especially devious and challenging to me.
评论 #29269460 未加载
cntlzwover 3 years ago
How do rust crates compare with something like maven or npm? It looks like some issues for example Typosquatting can be done in all of these dependency managers.
评论 #29266992 未加载
评论 #29266591 未加载
评论 #29267700 未加载
评论 #29266397 未加载
评论 #29266443 未加载
peterth3over 3 years ago
Discussion on &#x2F;r&#x2F;rust about this article:<p><a href="https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;qw3w01&#x2F;backdooring_rust_crates_for_fun_and_profit&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;qw3w01&#x2F;backdooring_ru...</a>
verdvermover 3 years ago
I wrote <a href="https:&#x2F;&#x2F;verdverm.com&#x2F;go-mods&#x2F;" rel="nofollow">https:&#x2F;&#x2F;verdverm.com&#x2F;go-mods&#x2F;</a> to talk about ways Go avoids some of these pitfalls. The forethought that went into `go mod` is one of the reasons I like and trust Go
评论 #29268953 未加载
评论 #29269344 未加载
caffeineover 3 years ago
Seems like you could address with a super-crate that includes &quot;trusted&quot; crate releases as &quot;features&quot;<p>That crate could involve some automation like:<p>* Checking that the code in the crate matches the code in Github<p>* Checking whether the latest commit is from a new committer, or whether there is any code comitted by a user not in a whitelist,<p>* Checking whether the package has any known security advisories<p>* Checking that crate signatures match some whitelist<p>* Running a project that includes the crate in a sandbox and seeing whether there are any files accessed, network accesses, etc. that were not pre-whitelisted<p>New versions of included crates would have to go through this battery of checks before they get bumped in the super-crate.<p>Crates that want to be included as features of super-crate or that need to change&#x2F;add significant functionality, or add dependencies, would need to make a PR to update the relevant whitelists, which could then be reviewed by the super-crate team
评论 #29267990 未加载
carlhjerpeover 3 years ago
Nobody is mentioning C#, but my experience there is that I rely on a lot less dependencies and a rather big standard library from Microsoft.<p>Microsoft has been splitting the standard library into separate dependencies now, but they&#x27;re still maintained by them and I feel safe depending on them.
Lifelarperover 3 years ago
&gt; I’m not sure if it’s by bots or real persons<p>The bot usage is a significant amount of the low level noise, I&#x27;ve published things of no use to anyone and they always rack up a lot of dl&#x27;s despite no one practically using them for a long time.<p>&gt; Firstly, a bigger standard library would reduce the need for external dependencies<p>There&#x27;s years worth of the same arguments tiringly made over and over again (same with namespacing) on the rust forum, everyone has played their hand on this issue a dozen times now, the community clearly has a majority stance on such things.<p>&gt; A variant of the previous technique is to use the --allow-dirty flag of the cargo publish command.<p>Please correct me if I&#x27;m wrong but thought that flag simply allows uncommitted changes to be published, the source is still availabile for anyone to view on crates.io<p>&gt; We&#x27;re sorry but this website doesn&#x27;t work properly without JavaScript enabled. Please enable it to continue.<p>Works perfectly fine for me. Maybe you couldn&#x27;t serve me a gdpr or something. Thankfully I can keep it turned off for now :)
loegover 3 years ago
You don’t really need the ‘—allow-dirty’ flag to do as the author claims. There’s no enforcement that the local git commit is ever published to a public repo.
pornelover 3 years ago
<a href="https:&#x2F;&#x2F;lib.rs&#x2F;cargo-crev" rel="nofollow">https:&#x2F;&#x2F;lib.rs&#x2F;cargo-crev</a> tries to address this.<p>It allows you to review the actual published source of your dependencies. It then can check whether your project only uses reviewed dependencies.<p>Reviewing everything is of course a lot of work, so there’s an option to mark crate owners as trusted, and also reuse code reviews made by people you trust.
mullrover 3 years ago
What are people doing about this on the client side? The solution that comes to mind is to do all my Rust builds in a sandbox of some kind, but with rust-analyzer involved, I&#x27;d likely have to put my editor in there as well.
评论 #29266582 未加载
zelosover 3 years ago
&gt; How to protect?<p>&gt; By pinning an exact version of a dependency, tokio = &quot;=1.0.0&quot; for example, but then you lose the bug fixes.<p>Surely no one uses version ranges in production? Is the default really not to use an exact version for crates?
评论 #29267446 未加载
评论 #29266865 未加载
gsprover 3 years ago
I love Rust, but it&#x27;s particularly frustrating to me how it (nearly) forces you to use a single centralized package repository. Shameless plug for an issue: <a href="https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;cargo&#x2F;issues&#x2F;10045" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;cargo&#x2F;issues&#x2F;10045</a><p>I don&#x27;t have a gripe with crates.io per se, but that the tooling doesn&#x27;t work offline and works poorly without crates.io is a real problem.
hn8788over 3 years ago
Stuff like this is why the place I work for decided not to use Rust as a replacement for future C projects. The devs evaluating it loved the language, and said they were more productive with it than they were with C, but being forced to either use no external dependencies, or audit tons of crates published by random people, made it a non-starter.
评论 #29271561 未加载
评论 #29270148 未加载
评论 #29270339 未加载
ferdowsiover 3 years ago
The anemic standard library in Rust always seemed like a disaster waiting to happen. Javascript gets heaps of deserved criticism for its standard library, but at I can generate a SHA-256 without needing to pull in a third party library.
dathinabover 3 years ago
While the thinks mentioned are a thing, his recommendations and interpretation of them seems often strange for me.<p>&gt; Typosquatting<p>Well known problem of more or less any open repo, namespaces do not solve it, they just shift the problem, maybe even make it more complex.<p>&gt; Misleading name<p>Again not cargo specific and not specific to flat namespaces either.<p>Namespaces help with first party packages from the same authors (but then it&#x27;s not too hard to check the authors, but annoying; Annoying is insecure). But namespaces do not help with 3rd party libraries. I.e. many (most?) `tokio-` libraries are 3rd party libraries made to work with tokio, not libraries from the `tokio` authors.<p>&gt; Transitive dependencies<p>Again something inherent to all package managers.<p>Through some ecosystems like npm are worse due to using more smaller packages.<p>In my experience while most rust crates have many dependencies most of them are to the same set of packages (like thiserror, anyhow, serde, etc.).<p>Anyway trying to avoid unnecessary dependencies is generally not a bad idea.<p>&gt; “x.x.1” Update<p>Basically: If you update a dependency you update a dependency, surprise.<p>Anyway using a `=` dependency is a anti-pattern which produces an endless amount of headaches and incompatibilities especially with libraries using `=` imports. There is a reason lock-fiels exists and `cargo update` doesn&#x27;t run by default.<p>&gt; Malicious update<p>This point make no sense as:<p>- cargo is not specific to the version control system you use it has some helpers for some vc systems, but that&#x27;s it.<p>- git tags are settable arbitrarily (and can be &quot;moved&quot;).<p>- You get the source from crates.io, not GitHub.<p>So the only way this can be a security vulnerability if you believe that reviewing not the source you use but source code from a different source is a good idea, while also trusting git tags while not fully trusting the author who sets the tags????<p>Just review the source code which you use, uploads to crates.io are immutable and you can download and read them.<p>&gt; Run code before main<p>Neet to point it out, but not specific to either rust and even less to cargo&#x2F;crates.io. It&#x27;s specific to the systems binary file format and how binaries are executed.<p>&gt; principles of Rust is no life before main<p>A design principal for the rust language, not a security statements.<p>Anyway review the source code you use, not source code form a different source you believe should be the same (unspecific of rust).<p>Rust could also improve on this by warning if (transitive) dependencies links to .ctor or similar.<p>&gt; Malicious macros<p>Code generation is an interesting aspect to analyze across languages. Most have it, some like rust at compiler time and first calls, other at compiler time but second class and others at runtime (e.g. Java reflections).<p>It&#x27;s definitely an area where rust has a lot of potential to improve (e.g. default-wasm sandbox most proc-macros or similar).<p>It&#x27;s also unavoidable in some cases (e.g. building external dependencies).<p>Additionally I would argue you probably could find a way to have code which somehow allows you to start running code when it&#x27;s compiled due to you crafting the code in a way which triggers buffer overflows and similar in the underlying compiler (e.g. LLVM).<p>You also tend to run tests...<p>So theoretically you always should sandbox your IDE&#x2F;project, even if you develop for a language which doesn&#x27;t has compiler time code generation.<p>As a side-note vscode ask you if you trust a project you open, if not it will change some settings for the project and rust-analyzer can be configured to no run build-scripts and proc-macros. (I haven&#x27;t tested if not trusting automatically also makes rust-analyzer not run things.).<p>&gt; a bigger standard library would reduce the need for external [..]<p>no, it doesn&#x27;t reduce the need. See python. Or see how even some features in rusts standard library are frequently not used but instead externally libraries are used, e.g. parkinlot or crossbeam.<p>Similar having 10 instead of 1 dependency might not decrease security if that 10 are a bundle from the same author in the same CI and have not (relevant) more code then if they where just 1 dependency.<p>What you want is reducing the number of trusted entities (!=not packaged) and trusted lines of code.<p>So having a group which manages a set of widely used packages with tight security would roughly be as helpful for the problem as having a bigger standard library, but much more practical. To some degree the rust nursery was going in that direction (but didn&#x27;t reach that goal).<p>&gt; Rust supports git dependencies.<p>It also allows pinning versions in Cargo.toml, pinning versions in lock-files and is immutable.<p>Git dependencies are prone in making you miss security updates, similar 3rd party audits are likely done on the code uploaded to crates.io, not the one on GitHub.<p>If you want to review all dependencies, and make sure to use them etc. then it&#x27;s probably best to vendor all of them, and set thinks up so that your dev system can only see&#x2F;reach vendored packages, while from time to time updating them based on crates.io and on diffs of the crates.io uploads (not GitHub).
rvzover 3 years ago
&gt; As Rust is designed for sensitive applications where reliability is important such as embedded or blockchain-like projects, it can raise concerns.<p>This is why I get very concerned with Rust projects using tons and tons of external crates. Especially cryptocurrency projects using Rust.<p>These sort of techniques can be used to compromise lots of them at once which in the very worst case can lead to loss of funds and is irreversible.<p>Unfortunately we will see the same issues found in NPM be found in crates.io with cargo.<p>Oh dear.
评论 #29266365 未加载
dane-pgpover 3 years ago
&gt; Actually, my num_cpu crate has been downloaded 24 times in less than 24 hours, but I’m not sure if it’s by bots or real persons.<p>Presumably the author could include some payload which phones home with a randomly generated ID, to detect how many machines the package could take control over. That&#x27;s probably more meaningful than trying to decide whether the package was downloaded by a &quot;bot&quot;, and wouldn&#x27;t involve any GDPR-breaking information.
评论 #29266330 未加载
评论 #29266400 未加载
评论 #29266257 未加载
infogulchover 3 years ago
I&#x27;d like to see a notification when the repo tag contents doesn&#x27;t match the cargo tag version.
uncomputationover 3 years ago
IMO some simple (not easy, but simple) solutions would go a long way here.<p>- Support name spacing<p>- Support specifying non-crates.io server (docket does this)<p>- Throw warnings when the Git tag (if applicable) contents do not match the Cargo upload. Rate limit package owners so they are encouraged to set their tags right the first time and not move around<p>RE: compile time execution. This is a harder problem, common to any binary file distribution.
评论 #29267994 未加载
3r8Oltr0ziouVDMover 3 years ago
We should switch to using pure functional languages by default. Most of the packages don&#x27;t need to do any side effects and only perform pure calculations. In a pure functional language it is obvious from function signatures if these functions are able to perform side effects, so it&#x27;s not possible to hide a backdoor inside a pure function. An average project would depend only on a few impure packages, such as a HTTP client or a framework, therefore it would be much easier to verify the security (for small impure packages you could just inspect their code yourself, and bigger packages like frameworks would have many contributors that check the code and strict policies about their security). Languages like Rust and C++ for which the pure functional model doesn&#x27;t work should then only be used for performance critical code, and projects written in impure languages should avoid third-party dependencies as much as they can.
评论 #29267438 未加载
评论 #29267182 未加载
评论 #29267490 未加载
评论 #29267324 未加载