TL;DR — Key Takeaways
- A rapidly spreading Shai-Hulud supply-chain attack has compromised more than 1,280 npm packages with a combined 2+ billion monthly installs, after attackers hijacked the GitHub account of a key maintainer and published malicious updates with legitimate signatures.
- The malware silently executes during npm install, stealing GitHub, npm, AWS, Kubernetes, Vault, Slack, Stripe, SSH, VPN, and other secrets before spreading worm-like to additional maintainers and packages.
- Researchers warn the campaign is expanding by 50 to 100 newly infected packages every few minutes, impacting software tied to organizations including Deliveroo, OneReach, ServiceTitan, Picsart, and Qlik.
Researchers at Aikido Security and Endor Labs are tracking a fast-spreading supply-chain attack that is compromising a wide range of npm software packages that combined have more than 2 billion installs a month and is stealing a wide range of secrets and other information.
According to Ilyas Makari, malware researcher with Aikido, the bad actor on the morning of August 4, compromised the GitHub account of jaredwray, the maintainer behind keyv, a key-value storage library with about 127 million weekly npm downloads, and then used that access to spread information-stealing malware across the entire package family.
“The compromise was carried out by pushing malicious files directly to the main branch and then immediately cutting a new release, meaning the poisoned versions were published to npm with valid provenance signed by GitHub Actions,” Makari wrote in a report.
Kiran Raj, security researcher and engineer with Endor Labs, wrote that “the pattern is consistent across them: an npm publishing token was stolen and used to push malicious versions, in most cases a CI or service-account token likely harvested from a build runner that had itself installed a poisoned dependency.”
It appears to be an attack linked to Shai-Hulud, the notorious worm that rose to prominence late last year and has continued to haunt developers and the open source software packages they use. After stealing a range of credentials and other information from victims’ systems, the data is exfiltrated to a public GitHub repository whose description says “Shai-Hulud: Here We Go Again.”
In his last update, Makari wrote that 868 packages across 1381 versions had been compromised by the malware. The packages combined account for more than 2 billion monthly installs.
Since Makari’s update, the worm has spread significantly. According to Charlie Eriksen, security researcher at Aikido, researchers are seeing 50 to 100 new packages infected every few minutes, reaching more than 1,280 packages.
A Fast-Spreading Infection
The massive attack is spreading so quickly that Aikido researchers couldn’t keep pace in their blog.
At one point, Eriksen posted to X that it had been about 25 minutes since the latest infected package appeared, though he predicted that “wave 2 of the attack will hit any minute now.” An hour earlier, he wrote that the attackers were “still trying to debug their attack” and were “deleting all issues posted about it in the repos.”
The threat actors were able to quickly scale their attack. The maintainer behind keyv also controls eight other packages, including caching utilities like flat-cache, with 565 million downloads a month, file-entry-cache (557 million a month), cacheable/utils (34 million), cacheable (29 million), cacheable/memory (28 million), and cache-manager (16 million).
Company Packages Infected
It’s also spreading to other maintainers and packages, including those of organizations such as online food and grocery delivery company Deliveroo, AI orchestration and automation platform vendor OneReach, and ServiceTitan, which makes cloud-based field service management software.
Also seeing their npm packages infected are Picsart, which offers an AI-powered photo and video editing platform, and Qlik, whose platform offers business intelligence, data integration, and other capabilities.
A Payload of Info-Stealers
According to Makari, every infected package received two files – setup.mjs and Math_Symbol.js, and a preinstall entry.
“Anyone who ran npm install against an affected version would have had setup.mjs execute automatically before their install completed,” he wrote. “setup.mjs is a heavily obfuscated dropper. Its only job is to silently download the Bun JavaScript runtime from github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/ and use it to execute the real payload, Math_Symbol.js.”
Math_Symbol.js a 728 KB JavaScript file that is highly obfuscated and delivers credential stealers that grab secrets from victims’ systems, encrypts what it finds, and then exfiltrates it to the Shai-Hulud-flavored GitHub repository. Through the payload, the malware can move worm-like to infect packages of other maintainers who have installed one of the compromised packages.
Tokens, Secrets are Stolen
The payload also includes a number of credential extractors that each target a different secret store in a victim’s system. The stolen information includes npm and GitHub tokens, Amazon Web Services (AWS) credentials, Kubernetes secrets, HashiCorp Vault tokens, and Stripe and Slack tokens.
A scanner that can run on macOS and Linux systems runs about 200 glob patterns across a computer’s filesystem, looking for such information as private keys, SSH keys and configuration data, Terraform state files, Docker registry credentials, KeePass databases, and VPN and IDE configurations.
The malware skips over files that are greater than 5 MB and uses up to 64 concurrent reads.
“A generic regex engine is also applied across all scanned files, flagging PEM private keys, SSH public keys, Azure storage keys, database connection strings with embedded credentials, and generic key=value patterns matching common secret field names,” Makari wrote.
What To Do
Endor Lab’s Raj wrote that organizations need to pin or roll back infected packages to before they were compromised, use npm, yarn and pnpm overrides for keyv, flat-cache, and file-entry-cache – “they are usually transitive,” he wrote – and rotate credentials on any machine or runner that ran npm install after 09:30 UTC. That includes npm tokens, GitHub PATs, cloud keys, CI secrets, and Vault tokens.
They should also search lockfiles and CI logs for malicious versions, including devDependencies, and prefer –ignore-scripts in CI.
“It blocks this class of install-hook malware,” he said.
Frequently Asked Questions
How can a compromised npm package spread malware to other maintainers and projects?
The malware runs automatically through a malicious preinstall script when an affected package is installed. It then searches the victim’s system for npm and GitHub tokens, CI credentials and other secrets that can be used to publish poisoned versions of additional packages, allowing the attack to spread like a software supply-chain worm.
Why does valid GitHub Actions provenance not guarantee that an npm package is safe?
Provenance confirms where and how a package was built and published, but it does not prove that the underlying source code is trustworthy. In this attack, malicious files were pushed through a compromised maintainer account and released through the legitimate workflow, giving the poisoned packages valid provenance.
What should organizations do if an affected package may have run in their environment?
Teams should immediately identify and roll back compromised versions, search lockfiles and CI logs, and rotate any npm tokens, GitHub personal access tokens, cloud credentials, CI secrets and Vault tokens exposed on affected machines or runners. Using dependency overrides and --ignore-scripts in CI can also reduce the risk from malicious installation hooks.

