About release dead code crates

Mail queries are made for crates that have not been maintained for at least 2 years, and if there is no response, the library is deleted and released. This prevents someone from taking the name and not using it

This has been discussed before, and a major problem is that if anyone has a dependency on the deleted crate, it not only breaks their code, but also allows supply-chain attacks where a malicious user creates a new, malicious crate with the same name as the deleted one.

11 Likes

For what it's worth, we track unmaintained crates in the RustSec Security Advisory Database:

5 Likes

What does "maintained" mean?

While Rust isn't old enough yet, I've worked with libraries in C which haven't had an update in 10 years, as they are just "done".

14 Likes

You can review the WIP guidance we're crafting on that topic here:

tl;dr: crates where the author agrees it's unmaintained, or crates with non-communicative authors which are not receiving any updates/releases/etc

4 Likes

The supply-chain problem can be solved by allowing new maintainers only release a higher semver-major version. So if a crate stopped being maintained at v3.3.0, the new owner can only release v4.0.0, but not 3.3.1 nor 2.0.0. In typical usage this will prevent other users from automatically upgrading to a potentially-malicious crate. There can also be a required period in between when the crate is completely yanked and unusable, so that its active users will notice and remove the dead dependency.

5 Likes

What about a scheme using digital signatures? AFAIK, crate repositories (including crates.io) match based on the name of the crate alone. Given that, we can have the following scheme:

  1. When an author makes a release, they sign two documents. The first is a UTF-8 encoded plain text file containing the canonical name of the crate only. This is the exact name that you would use in your Cargo.toml file, and anywhere else that is mechanically verified or used. The second is the complete material that is being released, which must be signed with the same key.
  2. When you download a crate, you get both of these files, plus the keys to verify the signature. The verifying keys are put in your Cargo.lock file, or in .cargo, or wherever it's best to place it.
  3. When you build a crate, cargo verifies that signatures on both files is good, complaining loudly if the signatures on either are bad. It will also do this if it already has key material on file for that crate.

For someone to replace a well-known crate, they have to get people to accept the new keys before their replacement crate will be built and incorporated.

I think that this will require minimal changes. Basically, a new file (CrateRepositoryName.txt? Someone bikeshed this) that the crate author will need to sign before upload, and maybe some work on the crate repositories end to reject releases that don't have this file. After that, it becomes a matter of educating people, and eventually releasing the names of dead crates.

I think that the following table outlines the possible outcomes of good/bad signatures:

Name File Complete Material in Release Keys matching Result
Good signature Good signature Matches original Good crate, carry on
Good signature Good signature Doesn't match original Maybe a new maintainer? Verify before use.
Good signature Bad signature Matches original Corrupted crate, use a different version, contact author.
Good signature Bad signature Doesn't match original Supply chain attack! Report to rustsec ASAP!
Bad signature Good signature Matches original Corrupted crate, use a different version, contact author.
Bad signature Good signature Doesn't match original Supply chain attack! Report to rustsec ASAP!
Bad signature Bad signature Matches original Supply chain attack! Report to rustsec ASAP! (implies crates.io was hacked)
Bad signature Bad signature Doesn't match original See below

In the last line, if the signatures are bad and the keys don't match the original then there are a couple of possibilities.

First, the author may have updated their keys, but forgotten to update crates.io with the new keys. Report it as a bug to the author, and see if they put out a new release shortly. Note that it would be good practice for crate authors to keep the contents of new release identical to the old release, while just updating their keys; this lets automated tools verify that this was just an honest mistake as the contents of the release will remeain the same.

The other possibility is that someone is trying to do a supply chain attack, but has done a really, really bad job of it. Report it to rustsec, so that they can see if there is anything that can/should be done.

I think that crates.io can automatically triage some of the above. For those parts that are highly likely to be supply chain attacks, it could even report to rustsec automatically.

In that case, there's no real need to yank at all. The old versions can stay available for download, if the problem is just hogging the name and not the storage required. This might be confusing if the two crates would share the same landing page, so it would be better to add crates.io support for multiple pages of the same crate. However if the assumption is that the old crate is dead, findability of it is less important.

Getting people to manage keys correctly is really difficult. Even when they're strongly motivated to do so. People still lose keys to access cryptocurrency wallets worth large amounts of money.

Getting people to actually think about whether to accept or reject updated keys for their counterparties rather than blindly accept updated keys is even harder.

Adding key management to things needs to be thought about extremely carefully for usability, because otherwise you get a lot of friction for little real-world benefit.

3 Likes

I agree that getting people to manage their keys correctly is difficult. But I also think that it's the best way to deal with this problem. Supply chain attacks are real, and as rust gets to be bigger, it will become a bigger target to attack. Crypto is probably going to be the only realistic way of dealing with it...

I agree that supply chain attacks are a real problem. However, saying "something must be done" isn't the same as "this specific thing must be done."

The problem in this case is one of trusting software artifacts. The SLSA and SCITT standards which are developing (building off of COSE and in-toto) are a more compelling and complete solution to this problem that one that the Rust community could device independently.

2 Likes

I agree 100% with this. I misunderstood what you were saying; I thought that you were saying that because keys are difficult to manage, we should give up trying to solve the problem in a robust manner.

Thank you, I didn't know about those at all! Have you brought these to the attention of the rust secure code working group? As you say, they are much more complete standards than what we're discussing here.

I have now raised these in the Rust secure code working group Zulip channel. Thanks!

Speaking on behalf of the Rust Secure Code Working Group, we have been following and participating in various in-toto discussions for several years.

Adding anything like that to cargo itself seems rather tricky though. We've had a few issues open about that for several years:

There's also a tracking issue for a potential integration with Sigstore, which is currently being explored by RubyGems:

Note however that the Cargo team is overwhelmed with open PRs as there aren't enough reviewers for those PRs:

It would probably make sense to explore any of these integrations via a 3rd party tool, prototyping and proving them out in a way which doesn't require direct integration with Cargo or crates.io, and exploring a potential direct integration with Cargo as a next step.

6 Likes