Dependency managers security - it's time for a change
There is a lot of work being done to fix security issues for regular users on all operating systems. But what about those who create the software? Software developers are even more juicy targets for bad actors as our work gets distributed to end-users. But the current state of dependency managers security calls for a long-needed overhaul.
We are living in a world where we simply cannot trust dependencies downloaded from repositories. They are notoriously being attacked and that will not change - it will be a constant battle between repository operators and attackers.
What can we do to fix that, or at least lower the impact of a breach?
Problem: the impact of malicious dependencies
Dependency managers, such as
gradle and many, many others do not provide enough security for our systems. Packages are allowed to execute arbitrary code on our machines. We should not simply trust them to do no harm.
The impact of a malicious package is not contained to the project we are working on. It can access information from places outside of our project - such as keystores, saved browser cookies or access tokens, files from other projects, production AWS keys. The list goes on and on.
There is a lot of work done by repository operators to make sure that hosted dependencies are safe. And they do the best they can. Unfortunately, the history shows that it doesn’t always work and we cannot simply just rely on their efforts.
What can we do to mitigate this risk?
Solution: better sandboxing
The obvious solution to this problem is to isolate code executed by dependency managers. Every dependency manager could execute the code within a sandbox that limits access to the developer’s system. Unfortunately this is not easy. Dependencies sometimes need very different things from the host system and the manager needs to run on all popular operating systems.
However, we do have a tool that can enable us doing just that without rewriting those programs - Docker.
It runs on all major operating systems and can be configured to access almost everything within the host system. One major problem with this approach is that it requires knowledge of how Docker works and some
configuration on the developers part.
What can we do then?
I’ve built a wrapper around those tools called Depman. It solves the problem in many basic scenarios and allows enough customization for more advanced ones.
It works by adding an alias to your shell that redirects all dependency manager commands to a special docker container with necessary directories and resources mapped to the host machine.
Every workspace (basically, a directory where
compose.json or similar file is located) has its own configuration and data directory. Within that directory, all files from containers home are being persisted. This allows usage of dependency cache per project without risking one project corrupting them for another.
The container image and Dockerfile can be both configured, enabling support of more complicated environments.
It is currently in an early stage of development, so I encourage you to test it out and contribute:
There is another advantage of executing dependency managers with Docker - easier and better environment version management. It could potentially replace tools such as Node Version Manager, PHPenv or Virtualenv.
I will talk about them in the next post - stay tuned!
Do you have other commands that could use this kind of sandboxing? Let me know in the comments or send a merge request :)Post by: Witold Sosnowski