As a result of the compromise of the release process based on GitHub Actions in the TanStack project, the attacker managed to publish 84 malicious versions in the NPM repository, affecting 42 NPM packages from the TanStack stack. Some of the compromised packages had over 10 million downloads per week.
Access to the release publishing was obtained due to incorrect configuration of pull_request_target 'Pwn Request' in GitHub Actions (the specified mask in the settings led to the execution of pull_request_target for pull requests in external forks), poisoning the GitHub Actions cache through a fork and the ability to extract the OIDC token from the memory of the running runner process (Runner.Worker) by reading the contents of /proc//mem.
The NPM packages with malicious changes were published on May 11 from 22:20 to 22:26 (MSK), noticed after 20 minutes and blocked in an hour and a half. For each affected NPM package, two malicious versions were released, which integrated code to activate the mini-shai-hulud worm, searching for tokens and credentials in the current environment. If a token connecting to the NPM registry was found, the worm would automatically publish new malicious releases for packages under development in the current environment, contaminating the dependency tree. In this way, over 400 NPM packages that used TanStack packages as dependencies were compromised.
The worm was located in the file router_init.js and was activated when the affected package was installed manually by the developer or automatically in the continuous integration environment using the commands 'npm install', 'pnpm install', or 'yarn install'. After activation, the worm searched the system for tokens to NPM (~/.npmrc), AWS, GCP, Azure, HashiCorp, and Kubernetes K8s, as well as SSH private keys. The discovered data was sent to the attackers via the decentralized P2P messenger getsession.org.
The worm was designed to carry out destructive actions in the event of the intercepted NPM token being revoked — the system configured a periodic running of the script ~/.local/bin/gh-token-monitor.sh, which checked the token's activity every 60 seconds by accessing api.github.com/user, and if the token was revoked, it executed the command 'rm -rf ~/'.
Source: opennet.ru
