PostHog admits Shai-Hulud 2.0 was its biggest ever security bungle
PostHog says the Shai-Hulud 2.0 npm worm compromise was “the largest and most impactful security incident” it’s ever experienced after attackers slipped malicious releases into its JavaScript SDKs and tried to auto-loot developer credentials.
In a postmortem released by PostHog, one of the various package maintainers impacted by Shai-Hulud 2.0, the company says contaminated packages – which included core SDKs like posthog-node, posthog-js, and posthog-react-native – contained a pre-install script that ran automatically when the software was installed. That script ran TruffleHog to scan for credentials, exfiltrated any found secrets to new public GitHub repositories, then used stolen npm credentials to publish further malicious packages – enabling the worm to spread.
According to security boffins at Wiz who uncovered the second coming of the Shai-Hulud campaign, more than 25,000 developers had their secrets compromised within three days. Along with PostHog, affected packages include those provided by Zapier, AsyncAPI, ENS Domains, and Postman, several of which have thousands of weekly downloads.
Shai-Hulud 2.0 doesn’t just propagate like a typical trojan – it behaves like a full-blown worm. Once a compromised package is installed, the malware can steal not only npm or GitHub tokens, but also cloud credentials (AWS, Azure, GCP), CI/CD secrets, environment variables, and other sensitive data from developer machines or build systems.
PostHog says it revoked all compromised tokens, removed the malicious package versions, and began issuing “known-good” releases.
But the postmortem highlights a deeper, more structural danger: this wasn’t an accidental breach of a password or token, but a mistake in CI/CD workflow configuration that allowed malicious code from a pull request to run with enough privilege to grab high-value secrets.
A malicious pull request to PostHog’s repository triggered an automation script that ran with full project privileges. Because the workflow blindly executed code from the attacker’s branch, the intruder seized control: they exfiltrated a bot’s personal-access token, which had write permissions across the organization, then used that token to commit new malicious code.
Armed with those stolen credentials, the attacker deployed a modified lint workflow to harvest all GitHub secrets, including the npm publishing token. That token was then used to push the trojanized SDKs to npm – completing the immortal worm-in-your-dependency-tree.
PostHog says it is now adopting a “trusted publisher” model for npm releases, overhauling workflow change reviews, and disabling install-script execution in its CI/CD pipelines, among other hardening measures.
If this postmortem sounds uncomfortably familiar, that’s because it is – bots with big permissions, workflows doing jobs on autopilot, and dependencies updating with the enthusiasm of an intern who definitely didn’t read the docs. Turns out, that’s all a worm really needs. ®
READ MORE HERE
