Recent NPM package takeover incidents such as “coa” and “ua-parser-js” have affected organizations by the thousands and have emphasized the need for a monitoring system, alerting developers and the open source community of suspicious activities that might hint of an account takeover, and/or malicious packages being published.
Learning the lessons from these incidents, we have implemented ChainAlert, which continuously monitors new open source activities and will help minimize the damages from future attacks by closing the gap between takeover – to detection and mitigation.
Background
In late October, a threat actor (tracked as UNC3379 by Mandiant) gained access to the NPM user account of one of the owners of the popular package UAParser.js. The attack group published new versions of the package (0.7.29, 0.8.0, 1.0.0), which included a few malicious files, and an additional “preinstall” script in the “scripts” section in the package.json file. This new “preinstall” script was intended to trigger the execution of the malicious files upon package installation. The attacker’s final goal was to infect package users with both a crypto miner and credential stealer malware.
This attack was reported by a vigilant user on the project’s repository on GitHub, preventing what could have been the infection of millions of users.
Using the same techniques, and much of the same code, a similar attack occurred in early November on two other highly popular packages: “coa” and “rc.” Both packages were infected in a similar manner to the previous UAParser.js incident by an account takeover of the packages’ owners.
In this case, a bug in the attacker’s code that prompted an error upon installation facilitated early detection and mitigation.
In both cases, the suspicious activity was noticed by chance, or at least not by any dedicated mechanism. This means that the next potential account takeover and subsequent infection has a good chance of going unnoticed for a relatively long period of time, and possibly causing severe damages.
ChainAlert
Realizing that a swift detection mechanism can be the difference between thousands of infected developers machines to millions, we have created ChainAlert, a free service by Checkmarx, which is a monitoring system that observes the open source ecosystem, and alerts package maintainers and developers of potential user account takeover attacks, and/or suspicious package releases.
The ChainAlert cloud service continuously monitors all new open source package releases to NPM package manager to look for some of the characteristics of such attacks. (Other package managers will be supported in the future.)
Package Releases with a Missing Git Tag
It’s quite popular for packages to reference their Git repository, which hosts the package’s source code. Among other features, this Git repository includes a designated section for releases and tags.
When a project works in an orderly fashion, it has a matching Git release/tag for every release in the package manager – either done automatically or manually.
ChainAlert cloud service monitors and identifies any divergence from this pattern, e.g., a release in NPM that has no matching release in the VCS. This might imply an account takeover on NPM, and a release of a malicious package outside of the normal release process.
Package Releases with Newly Added Auto-install Scripts
To maximize the effect of the attack, threat actors often prefer to run their malicious code as soon as the package is installed, rather than waiting for some other triggers such as module import or a specific function call. That is why many attacks use the “scripts” feature in NPM packages.
The “scripts” section in the package.json file of an NPM package enables developers (and attackers) to run custom scripts with different triggers. Some of these scripts are configured to run automatically upon the installation of the package, such as “install”, “prepare”, “postinstall” and a few more, making them a preferred target for malicious actors writing infected packages.
ChainAlert looks at these scripts in each of the new releases and compares them to the previous release to identify the addition of these “on-install” scripts.
Package Releases by a New Maintainer
Applied exclusively on highly popular packages, this checks for newly added maintainers of the NPM package, and alerts if one of them is the publisher of the latest version.
Alerting The Ecosystem
If this alarm system was implemented at the time of the “ua-parser-js” and “coa” attacks had taken place, ChainAlert would have flagged the new releases as suspicious.
Today, upon recognizing one of these suspicious signs, The ChainAlert cloud service automatically opens an issue on the GitHub repository related to the NPM package. For example:
Alerting The 2nd Wave
ChainAlert cloud service can also alert individual projects from suspicious package dependencies.
An individual project can subscribe by adding ChainAlert’s GitHub action to its repository. Once subscribed, the ChainAlert cloud service will create an issue on the project’s repository in case one of the suspicious activities as described above is detected in one of its dependencies.
This service is offered for free on the GitHub action marketplace.
2FA To the Rescue?
A few days ago, NPM rolled out their new policy enforcing 2FA on maintainers of the top 100 popular packages on the registry. This is another step toward mandatory 2FA to all maintainers on the package manager.
As shown before, obvious or reused passwords are in abundance among NPM maintainers, and hence, this new policy will likely prevent a substantial portion of account takeover attacks and dramatically reduce the attack surface for such activity.
Unfortunately, despite NPM’s efforts with this recent policy and other steps they have taken, account takeover is still a threat. One reason for that is the necessity of automation tokens as part of the CI/CD pipeline.
Requiring 2FA authentication inside an automated CI/CD pipeline defeats the automation purpose, and is not likely to be adopted by many developers. This leaves us again with a single token that grants an attacker, who possesses it, publishing permissions.
Conclusion
Account takeover of package managers’ users poses a real threat with a potentially huge impact. ChainAlert helps the open source community defend against this kind of supply chain attack reoccurrence by alerting in near real-time, helping facilitate rapid mitigation.
To sign up your GitHub repository for the free ChainAlert service, visit this link or look up “chainalert” on the GitHub Action Marketplace, then add ChainAlert action to your workflow.