A series of coordinated supply chain attacks (s1ngularity, Qix compromise, and Shai-Hulud) abused GitHub Actions and long-lived tokens to publish malicious npm packages and exfiltrate secrets, exposing thousands of repositories and leaking over 2,000 unique secrets. The incidents highlight phishing, unrotated credentials, and CI/CD workflow weaknesses as root causes and prompted mitigations like token rotation, GitHub hardening, and tools such as GuardDog and Supply-Chain Firewall. #s1ngularity #Shai-Hulud
Keypoints
- Attackers exploited the pull_request_target GitHub Actions trigger to steal npm publishing tokens and publish malicious Nx package versions containing telemetry.js credential-harvesting scripts.
- A phishing campaign against the Qix maintainer (using support@npmjs[.]help) led to malicious browser-based crypto-stealing code in 18+ packages (including debug, chalk, ansi-styles) with >2.5M downloads but limited financial loss reported.
- Stolen tokens were reused without rotation to perform large-scale repository exposure: private repos were made public (appending -migration) and stolen secrets were posted to attacker-controlled public GitHub repos (e.g., s1ngularity-repository).
- Shai-Hulud used a self-replicating worm and GitHub Actions to exfiltrate secrets to webhook[.]site and further propagate across npm projects, demonstrating rapid attacker pivoting and automation via CI/CD.
- Root causes include unrotated long-lived credentials, insecure GitHub Actions configurations that run untrusted pull request code, and successful phishing; mitigations include token rotation, fine-grained tokens, FIDO 2FA, and CI/CD hardening.
- Responses included repository disabling by GitHub, Nx security fixes, advisories and blog posts for mitigation guidance, and new features from pnpm/yarn (minimum package age) plus proposed npm publishing limits and FIDO migration by GitHub.
- Detection and prevention tooling recommended: Datadog SCA/SAST rules for identifying compromised packages and GitHub Actions vulnerabilities, plus open-source tools GuardDog and Supply-Chain Firewall to block malicious packages.
MITRE Techniques
- [T1608 ] Abuse of GitHub Actions workflow triggers – Used pull_request_target to execute attacker-controlled code and steal publishing tokens (“…exploiting a vulnerability in the pull_request_target trigger in the GitHub Actions workflow, which allowed them to steal an npm publishing token…”).
- [T1078 ] Valid Accounts – Phishing was used to gain maintainer access (Qix) via a forged 2FA reset email (“…using a fraudulent domain, support@npmjs[.]help, the attackers imitated a two-factor authentication (2FA) reset email to gain initial access…”).
- [T1059 ] Command and Scripting Interpreter – Post-install script telemetry.js executed on victim machines to harvest credentials (“…Each compromised package contained a credential-harvesting malware script called telemetry.js, which executed as a post-install script…”).
- [T1537 ] Transfer Data to Cloud Account – Exfiltration of stolen data to public GitHub repositories under victims’ accounts (“…the attackers then exfiltrated the stolen data to newly created, public GitHub repositories under the victims’ own accounts…”).
- [T1098 ] Account Manipulation – Changing repository visibility and appending -migration to names to expose more data (“…stolen GitHub tokens were used to change thousands of private repositories to public… appending “-migration” to the repository names.”).
- [T1566 ] Phishing – Use of phishing emails and typosquatted domains to compromise maintainers (“…phishing email disguised as an npm 2FA reset request… In July 2025, attackers spoofed an npm site to target developers through a typosquatted domain.”).
- [T1195 ] Supply Chain Compromise – Publishing malicious npm package versions to the registry to infect downstream users (“…they published malicious versions of the packages to the npm registry… contained a credential-harvesting malware script…”).
- [T1574 ] Hijack Execution Flow – Injected malicious GitHub Actions workflows and scripts to steal secrets and propagate (“…leveraged a compromised PyPI maintainer account to insert a malicious GitHub Actions workflow…designed to steal secrets from the Actions environment…”).
Indicators of Compromise
- [File/Script ] Malicious post-install script – telemetry.js found in compromised Nx package versions.
- [Email/Domain ] Phishing domain used for 2FA spoofing – support@npmjs[.]help (used to target Qix maintainer).
- [Repository Names ] Public exfiltration repositories – s1ngularity-repository (used to host stolen data) and repositories with -migration appended (Shai-Hulud propagation).
- [Endpoints ] Exfiltration destination – webhook[.]site (used to receive secrets from compromised GitHub Actions workflows).
- [Packages ] Compromised npm packages – Nx packages (s1ngularity), debug, chalk, ansi-styles (Qix compromise), and mention of cross-fetch and GraphQL-JS as similarly vulnerable projects.
- [Other ] Download/impact metrics – malicious package versions downloaded >2.5 million times and >2,000 unique secrets leaked (contextual indicators of large-scale impact).
Read more: https://securitylabs.datadoghq.com/articles/learnings-from-recent-npm-compromises/