11 comments

[ 2.8 ms ] story [ 36.2 ms ] thread
Instead of securing the "chain", we should instead isolate every library we import and run it under a sandbox. We should adopt the model of QubesOS. It follows security by isolation. There are lots of native sandboxing in linux kernel. Bubblewrap, landlock, gvisor and kata (containers, not native), microVMs, namespaces (user, network), etc
One downside of fine-grained sandboxing is the overhead, as each (function) call into a library now has to cross sandbox boundaries.

Even if we assume overhead is magically brought to zero, the real challenge is customizing the permission policy for each sandbox. I add, say, 5 new dependencies to my program, and now I have to review source code of each of those dependencies and determine what permissions their corresponding sandboxes get. The library that connects to a database server? Maybe it also needs filesystem access to cache things. The library that parses JSON buffers? Maybe it also needs network access to download the appropriate JSON schema on the fly. The library that processes payments? Maybe it also needs access to location information to do risk analysis.

Are all developers able to define the right policies for every dependency?

It might work if you run the library in a separate process. This will work better on a capability-based system (with proxy capabilities; this would have other benefits as well and not only security) than on Linux, although it might still be possible to implement. An alternative way to implement library sandboxing would be to implement the sandboxing at compile time, which would work on any system and not require a separate process, and has both advantages and disadvantages compared with the other way.
Docker does many things but 'convince code it's not running in a sandbox' ain't one of them. Nasty code can wait patiently for the right environment to get up to mischief.
This is something I've never totally understood when it comes to Rust's much loved memory safety vs. C's lack of memory safety. When it comes to replacing C code with Rust, aren't we just trading memory risk for supply chain risk?

Maybe one is more important than the other, I don't know. All the languages I use for work or hobbies are garbage collected and I'm not a security professional. But it does seem like the typical Rust program with it's massive number of "cargo adds" is an enormous attack surface.

No-one's forcing you to use crates published on the crates.io registry - cargo is perfectly happy to pull dependencies from a different public or private registry, elsewhere in the same repo, somewhere else on the filesystem, pinned to a git hash, or I think some other ways.

"We shouldn't use the thing that has memory safety built in because it also has a thriving ecosystem of open source dependencies available" is a very weird argument.

"Not made here syndrome" might actually not be a syndrome.
Not a computer security expert by any stretch of the imagination but why is this difficult to solve, don't do antiviruses check if some program is accessing tokens or something? Maybe even OSes need to have default protection against this, Chrome browser history and tokens.
All modern desktop operating systems are fundamentally flawed. They assume that any userspace program can access any user file. Many software is built atop of this assumption. Antivirus programs have hard job to distinguish between legit and malicious programs, since both have may access arbitrary files.
How much would it cost to just hire a team that will manually review every commit to every popular npm package and its dependencies? Is it possible to make it a working business? Seems like it will cost much less than total damage done by supply chain attacks