Maintaining A Stable Supply Chain During Unstable Times

| | |

Supply Chain Security - Digital Chain With global threats escalating on a daily basis, software developers must remain as vigilant as ever to keep their code secure from threats. The events of this week leading up to CVE-2022-23812 have highlighted this simple fact with a supply chain attack that has the whole infosec community digging through codebases for compromised packages.

How Did We Get Here?

It all began on March 7th when github user RIAEvangelist released an update to their popular NPM package called “node-ipc.” When run, this update would walk the underlying operating system similar to how ransomware would behave, but it would replace all files contents with a heart emoji instead of encrypting them. In some ways this action is more malicious than encryption as there is no decryption option for the affected files. Adding this functionality into an existing package creates what’s known as a supply chain attack. The way this attack works is that node developers will list something like the popular node framework Vue.js as a dependency for their projects. Vue.js in turn lists node-ipc as a dependency for it to build. With this chain of dependencies in place, when the developer builds their code, it will download Vue.js which will download node-ipc and bundle all of these dependencies into the developer’s finished project. Now when the developer goes to run their code, the malicious code is run as well, replacing all of their files with heart emojis. This would be terrible for a developer, however one would hope all of their important work would be stored in git or a similar source control system. The scenario which makes this kind of attack much more devastating is when code is compiled via an automated pipeline, as most projects today are. In this scenario, a developer would commit their code changes, their pipeline would compile the new code, pulling down fresh copies of all dependencies as it does so, and then deploys this now-infected application to their servers, where the production server and all data on it is replaced by heart emojis. A short while after releasing this malicious code, RIAEvangelist pushed another update to node-ipc, this time only changing the version number. Presumably this update was intended to trigger automated dependency upgrades to get the malicious code into more systems. A few hours later, as these changes were beginning to attract more and more negative attention, RIAEvangelist pushed a third and final update to remove the malicious sections. All of these updated versions were eventually removed entirely, leaving the original version as the “latest” copy.

The Code Is Gone, But The Threat Persists

Later that day, RIAEvangelist created another npm module called peacenotwar that they refer to as “protestware,” which, when run from a Russian or Belorussian machine, would create a file on the desktop containing a message of peace in many different languages. They describe the project as a “a non-destructive example of why controlling your node modules is important.” They also go on to say that this package serves as their “non-violent protest against Russia’s aggression that threatens the world right now.” While not destructive on its own, this new package also highlights the same threat to supply chains as the changes implemented in node-ipc and could easily be added to any other projects as a dependency to create another supply chain attack. While the malicious code has been removed, the trust RIAEvangelist has built up over their many years of developing node modules has been put into question by these recent actions. Any teams using packages by RIAEvangelist should at a minimum have a discussion about whether or not to continue using their other projects as dependencies. Just like any other dependency, a proper risk analysis should be done, and any risks that are accepted should be minimized as much as possible.

Protection Through Defense In Depth

Supply Chain Security - Digital Lock As is true for most threats, there are many different opinions on which route is the most effective for minimizing risk for external dependencies. The three main routes development teams choose to adopt are dependency pinning, forking, and supply chain scanning. These can be done independently to varying degrees or all together to create a much more robust solution. Pinning dependency versions means developers will specifically define which versions of dependencies they are willing to use. This can be specified in many different ways; explicit versions, explicit major or minor releases (allowing the latest minor or patch releases to be included without adjustments), or simply saying above or below a specific release. The more restrictive the pinning is, the more secure it will be, however it will also be more work to maintain if you wish to receive the latest updates and security patches for these dependencies. It should be noted that to avoid this most recent supply chain attack, developers would have needed to use at least a minor version pin as the malicious update was pushed as a patch release to v10.1. Forking is similar to version pinning, but instead of defining which version of a particular dependency you are willing to accept, you make a new repository out of the code you are willing to accept and merge updates from the main project into your own as necessary. This is much more work, but ensures you control every aspect of the dependency and can selectively pull in portions of the updates that you deem necessary. This option also gives developers the ability to merge in their own custom patches or features without requiring the knowledge or permission of the original dependency developer. Along the same vein as forking, some developers choose to use a local cache of dependencies. This can be achieved through solutions such as Artifactory. These local cache providers offer similar protections from supply chain attacks as forking a repository. The main difference being that instead of offering the ability to merge custom patches, local cache providers offer faster and more reliable package retrieval to speed up builds and remove unnecessary internet requests. Supply chain scanning works from the other side of the development process; it utilizes automated scans of the code, checking against updated lists of known vulnerabilities to determine if a build is secure or not. While this method is by no means perfect it can catch a lot of issues before they are even built with very little effort after the initial configuration of the scanner in a pipeline. Whatever option you determine to be the best method of protection, Foghorn Consulting is here to help you build it and keep your supply chain safe during these uncertain times!