Securing Crates

Like many other modern programming languages, Rust allows for developers to use other people's code. This is done through the usage of crates.

This does however open up the possibility of these crates being used maliciously to compromise the target system. Such Supply Chain attacks are becoming increasingly common in other languages often with a wide impact and catchy headlines via The Register.

I'm going to explore an idea I had that could be used by Rust or other languages to help mitigate these supply chain attacks.
Of course it is not possible to mitigate all attacks, some are exceedingly subtle and use clever tricks to hide the real intent. That said, a lot of good can be done by focusing on the easy to detect attacks.
The measures outlined are a good starting point and can be expanded upon once the base framework is in place. You can use the framework to increase the detection range without having to change the interface which makes it a powerful tool for malicious code.

My first observation is that the list of things that could be harmful to a computer system is actually quite small. These are:

  • File Deletion
  • File Write/Modify
  • File Read
  • Network Requests including:
    • DNS lookup
    • HTTP Get/POST
    • Sending Data on a port
    • Opening a port
  • Executing a command line script

These obviously aren't the only ways to compromise a system, but a lot of maliciousness can be traced back to these operations.

My next observation is that there are a small number of legitimate crates that use any of these actions and if they are used, generally they are quite specific.

Therefore it is not unreasonable that if these actions are present in a crate that is not expected to use them, that crate could be considered suspect.
That is, a struct helper crate is unlikely to need to do a DNS lookup. But a Stripe payment crate is expected to go to api.stripe.com. Therefore it stands to reason that you could make sure that users are made aware of what URLs are accessed in a crate. Once this is done, you could then whitelist these URLs in the project toml file.
If an unknown URL pops up, it would then be clear if it is malicious or not. The developer can then do some more investigation.

The same logic can be applied to files. It would be unusual for a library for it to delete random files without user interaction. This doesn't mean that there are exceptions to these rules, there are, but it is uncommon.
With automated checking for these patterns, we can greatly reduce the risk of external crates doing malicious things within our program. And if these actions are done, they can be outline explicitly.

This doesn't mean that all attempts to do things activities will be or can be picked up, but if we take away the easy option, bad actors will be required to use harder and more complex methods to perform them.
These will have their own signatures that can then be detected. This is where Rust's strictness helps as these patterns will almost certainly need unsafe blocks.

So now that we have identified that such checking is both practical and likely to be effective, how should this be actioned? The first course is to do a Proof of Concept. This can be run against the existing set of crates to see what surprises exist. I fully expect to find a handful of suspicious entries.

The next step requires more work. That would be integration into clippy, Crates.io or maybe even Cargo. There are benefits and downsides to all 3. It does depend a lot on how strict the Rust community wants to be.

I'd like to work with others to help build out a solution. I think this is a good idea for other languages to implement, but Rust has a reputation for security and the strictness really helps in making it hard to bypass detection.