Many developers already know that in some ecosystems, open source dependencies might run their custom code from packages when they are being installed. While this capability can be used for both good and evil, today we’ll focus on a legit use case that, when misused, can escalate and be used to compromise your organization’s supply chain.
If you haven’t guessed yet, I’m talking about downloading and linking external dependencies during the install process.
Most of the open source libraries that are distributed via the registries are self-sufficient. They incorporate all of the assets and materials needed to build, compile, or use a given package. However, there are cases where the package is either a binding (explained below) or uses a third-party package of a different language or technology in a way that prevents it from being shipped with the package.
To quote Wikipedia, language binding refers to “an API that provides glue code specifically made to allow a programming language to use a foreign library or operating system service (one that is not native to that language).”
How do library creators and maintainers deal with this? Upon installing the package, they download the external dependencies from the internet and use them during the build and/or execution process.
While this isn’t necessarily a bad practice, it creates a couple of issues within your open source supply chain:
The way I see it, two of the biggest risks related to external resources not embedded in the packages themselves are the risks associated with them disappearing or being tampered with.
The world of open source software is often compared to the wild-wild west — for good reason. Projects and developers come and go. They change jobs, languages, and career paths. Having externally downloaded dependencies means that you cannot just “download and store” all of the things that are needed. The software that you have running today on your local computer or on a production server might not be usable in a month. The result of this instability could be quite disastrous: imagine one of your critical package’s resources disappears just before a really important fix is supposed to hit production.
If you visualize an open source software supply chain it may turn out that it is more of a tree than a chain. A tree with some of its leaves well hidden from your sight.
External resources that are being fetched during the install process are exactly like those leaves. You may well know (even personally) some of the developers of the packages you use. You know they won’t go evil, but are you sure they also know and trust creators and maintainers of the packages that they download?
A great example of such behavior is visible in a popular Ruby package called `rdkafka-ruby`. This package is dependent on the `librdkafka` package of a different author written in C. Upon installation, its content is being downloaded.
There are few ways both package creators and package users can minimize the risks related to using open source components that rely on external resources.
As a package creator you can try a few of the following to improve your library usability:
Here’s an example of how to prevent potential tampering with the downloaded resource. If anything were to be changed in the external resource — which might happen — over time the installation process will be halted and an error message will be presented:
Unfortunately, as the end-user, your options are pretty limited. The most important thing is understanding the packages you are using and whether or not they use external resources like the ones described in this article.
Here are some easy ways you can check your dependencies to gain a better understanding of the packages you’re using:
At WhiteSource we use WhiteSource Diffend to keep track of cases like this. We open issues and offer help when we detect that a package uses external resources, in the hopes of helping to make the whole open source software ecosystem safer and healthier for everyone.
Join us next time for more supply chain security news and security tips!