Ideas (shoot them down): - Somehow tie keys to location. - Require two-step verification for all commits for packages with over 1000 downloads. (Assuming their phone isn't compromised if the keys are).
Ideas (shoot them down): - Somehow tie keys to location. - Require two-step verification for all commits for packages with over 1000 downloads. (Assuming their phone isn't compromised if the keys are).
https://reproducible-builds.org/docs/buy-in/
When it comes to verifying this, we need to have independent rebuilders that build these packages reproducibly, and can attest these rebuilds in a secure manner. I have been working with NYU Secure System Labs to try provide this to debian packages and we currently have a PoC for such a system.
https://reproducible-builds.org/docs/sharing-certifications/
https://ssl.engineering.nyu.edu/blog/2019-01-18-in-toto-pari...
But I think this goes in the right direction.
You will likely have to create patches for those piece of softwares that create a different artifact every time are built.
There are a few other challenges but in my humble opinion, it is worthwhile to strive to write your own software with "reproducible builts" in mind so everybody can verify if something was altered.
This is hard on distributions as we are suppose to support all the ecosystems. But for rubygems, pypi, go, rust, npm and so on this is a easier problem to solve if they want to. But even with all these challenges, Debian is at 94% reproducible packages, and Arch is edging closer to 80%.
Introducing non-determinism into your build process is something that should be removed, and all ecosystems should be aligned in this effort.
Weekly blog posts are written about the current efforts. https://reproducible-builds.org/blog/
Of course, this adds a big deliberate barrier to participation - newcomers have to get their key signed by an existing Debian developers. There are real security/usability tradeoffs, and at the moment people seem to have default-chosen "anyone can add packages really easily", resulting in a Cambrian explosion of packages.
A non-exhaustive list of things that could be done...
- Improve repository security (e.g. stronger authentication requirements). Problem here is most of the repositories are non-profit and this costs money. Also there's a risk that if you increase friction for developers, they'll go elsewhere.
- Require library signing. This has some potential benefits (may even have stopped this attack) but again increased friction for developers and management overhead for repositories.
- Curation of libraries. Actually pay some people to review the code in the libraries. This doesn't scale easily when you consider the volume that places like NPM have.
- Sandbox code modules
If a library doesn't need any permissions, and it's not granted any, then attempts to e.g. access the filesystem or network will throw exceptions. The JVM can do this, but it's not well documented how to use it.
Found the blanket statement for npm.
How about instead of reviewing 1 library of 10k lines that does everything, you review 10 focused modules for a total of 1k lines?
Also modules like left-pad don’t change that often so you probably have to review only changes in the top modules.
We need to stop this mentality that dependency count should be low. Look at total LOC and you’ll probably find that it’s not as bad as people like to paint it.
1) Signing should always happen. Publish time + hashes of external resources should be taken into account to prevent meddling with things after the fact.
2- a much harder solution) Don't use so many libraries.
In this way I think it's borderline impossible. Of course this vuln targeted `bootstrap-sass`.. it's basically a default gem for new rails installations since bootstrap is so commonly used.
Actually, rails 6.0 not only installs dependencies for you upon generating a new app, but it downloads yarn and installs 602 dependencies too.
It's a miracle we do anything as programmers.
But now you will move at the pace of a bacteria on a snail. But since the company will probably introduce vulnerability bugs in the code they write, it is probably not a very good idea.
We are using open source and free packages to save time and move fast. Security and speed/usability have tradeoffs.
The paranoid will do everything in their knowledge to protect themselves but they will move slowly. The naive will not do anything and sooner than later will get burnt.
Assuming you trust your current modules and you can trust that they will not be altered, you can lock down the dependencies. But now monitor and updating a library when a bug or vulnerability is found in a modules become another burden.
Those actors that have the budget, patience and the motivation will always find a way in.
I sometimes feel quite sad about the real situation but there is not such a thing as perfect security.
That said some of the suggestions I see here will dramatically improve the situation with a relatively small effort. 2FA and reproducible builds for example.
One that comes closer is vcpkg [1], which is the Microsoft-run package manager for native C++ packages. It works by having the list of packages and recipes to build them (which it calls "ports") stored in a single repository. All requests to update them are submitted as pull requests and must be approved by Microsoft to enter the main repository.
I'm not necessarily saying whether this is a good or bad idea. Certainly it is a very different situation: only libraries that are already popular are considered, often the ports are submitted/maintained by different people than the library authors, and writing a port to build a library on multiple platforms may require significantly more work than just pointing at an existing GitHub repo. I just point to it as an alternative idea that has had some success.
[1] https://brew.sh/
Just require 2fa everywhere. We're way past the point where password-only is enough if you distribute software.
Package distribution platforms could also ensure that your package comes from a tagged/signed commit in a selected repo. Reproducible builds could help here too. Finally package signing itself and possibly WoT for authors. (Where either the author has to trust the dependencies or you have to explicitly trust all of them)
So, not trusting third parties is the only way and with that language level capability based security can help. Although this is pretty far from common programming languages where any function can access any file, environment variable, global variable, constant, socket, etc.