A supply-chain attack is an indirect attack which targets the tools, automatic software updates or supply chain in general, in order to introduce malicious code or dependencies into existing software, without the developers being aware. External package dependencies, which are fetched from public repositories during a build process, can pose an opportunity allowing attackers to add backdoors during builds and get access to the crown jewels.
This is the third post in our series on the history of supply chain attacks. This post will cover the importance of maintaining high password hygiene of developer accounts, keeping a strong authentication policy, following best practices when working with open source packages and steps to reduce risks for supply chain attack, specifically on your build environment.
The ESLint Attack
In 2018, ESLint was targeted in yet another supply chain attack. An attacker compromised the npm account of an ESLint maintainer via a third-party breach, revealing that he had used the same login and password details across multiple accounts and did not have two-factor authentication enabled on his npm account. The attacker was thus able to test leaked logins from other breaches against the npm account, a method known as “credential stuffing”.
After compromise, the attacker modified package.json in both firstname.lastname@example.org and email@example.com, adding a postinstall script to run build.js and uploaded to the npm registry.
- firstname.lastname@example.org, a scope analysis library, is a dependency of several popular packages, including some older versions of eslint and the latest versions of babel-eslint and webpack.
- email@example.com is a configuration used internally by the ESLint team, with very little usage elsewhere.
On installation, the malicious packages downloaded and executed code from pastebin.com which sent the contents of the user’s .npmrc file to the attacker. An .npmrc file typically contains access tokens for publishing to npm. In this case, these malicious packages were spotted in about 40 minutes. Once the ESLint team was notified, the pastebin.com link containing malicious code was taken down. The npm team unpublished firstname.lastname@example.org after being contacted by an ESLint maintainer, and ESLint team published email@example.com with the code from firstname.lastname@example.org so that caches could pick up the new version. npm revoked all access tokens generated before 2018-07-12 12:30 UTC (an hour or so since the attack was reported). As a result, all access tokens compromised by this attack should no longer be usable. 40 minutes sounds like a short time, but npm is seeing ~2B downloads per day, so only 54M downloads occurred during this time. For each one that was ESLint, the attacker got publish control of that next user’s repo. And so on, potentially causing a wide impact.
It is worth mentioning that at the same year, Gentoo was attacked in the same manner due to a developer using a weak password across multiple sites, including a GitHub account. By stealing the victim’s GitHub account, where Gentoo kept backups of its source code, the attacker was able add their own malicious code, designed to wipe user content, to the repository. Meanwhile, the account’s actual owner was locked out for nearly an entire week. In fact, the user losing access to the account was the only way the attack was even detected. In the aftermath, Gentoo had to declare all of their source code compromised and reverted to previous uncompromised commits.
The ESLint attack (as well as the one on Gentoo) not only revealed just how critical the practice of good password hygiene really is but demonstrated just how dangerous malicious code can be when unleashed on a highly trusted point in the supply chain that most users take for granted without a second thought. Worse yet, attackers with stolen accounts are often able to remain hidden for weeks or months at a time, allowing them space to target additional victims. With the hindsight of this incident, we have a few recommendations to reduce the risk of exposing to similar attacks and reduce their impact :
- Maintain high password hygiene:
- Follow open source packages secure development best practices:
- Avoid as much as possible using any services that auto-merge dependency upgrades.
- Use a lockfile (package-lock.json or yarn.lock) to prevent the auto-install of new packages.
- Enforce least privilege policies to reduce the scope of access to your repositories, especially on people who have access to publish.
- Continuously scan your source code repository for any secrets and access keys that can be obtained, if compromised. If found, revoke and remove them to keep your repository as secure as possible.
How Cycode Can Help
Crises are a time for the community to come together. As such, Cycode is offering a free code repository security assessment to any organization that is looking to harden their development infrastructure. Alternatively, if there is some other way we can help your organization, please get in touch with us.