On Monday, the second wave of Shai-Hulud (Shai-Hulud 2.0), also referred to as “The Second Coming” by its campaign operators, shocked the world. While it is heart-warming to see many entities have published blogs about it, the world is still very much reacting to it. Forty-eight hours later, many organizations are still in the middle of responding to this incident. To help the community better understand the mechanics behind this attack and what actionable steps they could take to respond to this attack and to prevent future occurrences, this blog is going to deep dive into the attack chain, and what to do about it.
What is Shai-Hulud 2.0?
SHA1-Hulud is the second, more aggressive wave of the Shai-Hulud npm worm originally observed in September 2025. It abuses compromised maintainer accounts to publish trojanized npm packages that execute malicious preinstall scripts, steal secrets, propagate across the ecosystem, and, in some failure cases, wipe the victim’s home directory.
Key differences vs the first wave (Shai-Hulud 1.0):
- Executes earlier in the lifecycle (during preinstall instead of later hooks), hitting CI/CD phases harder.
- Uses a Bun-based loader (setup_bun.js → bun_environment.js) instead of only Node.js to evade defenses tuned for Node.
- Adds malicious GitHub Actions workflows and a self-hosted runner (SHA1HULUD) for persistence and remote code execution.
- Introduces conditional wiper behavior if it can’t successfully steal credentials or establish an exfiltration channel.
The Bottom line
Shai-Hulud 2.0 is a sophisticated, mass-scale software supply chain attack combining:
- Malicious npm package injection via maintainer account compromise
- Bun-based loader obfuscation
- CI/CD persistence
- GitHub workflow backdoors
- Cloud credential theft
- Repo hijacking
- Worm-like propagation
- Conditional destructive wiper behavior
This represents a critical turning point in JavaScript ecosystem security and an indicator of the complexity and scale of future software supply chain security attacks. Compromise no longer stops at the package-level supply chain, but spreads into infrastructure, cloud accounts, DevOps ecosystems, and developer endpoints. “We are not a software company” is no longer a sufficient reason, as many are experimenting with AI and big data. “We have an SCA (Software Composition Analysis) tool is no longer sufficient to protect you against these types of attacks.
Known Impacts
Many organizations are still assessing the impact while potentially discovering new victims. At the time of this writing, below is what we know across a number of published data (Note: actual numbers varied by different vendors at time of snapshot, I am providing the best known estimates):
| Category | Impact |
| Compromised GitHub Repos | 25000+ |
| Compromised/Republished npm Packages | 492-800+ |
| Affected Maintainers | ~350+ |
| Total Exposed Secrets | 14,206 |
| Still-Valid Secrets During Analysis | 2,485 |
| GitHub PATs Stolen | 775 |
| AWS Keys Stolen | 373 |
| GCP Keys Stolen | 300 |
| Azure Keys Stolen | 115 |
| Rogue Repos Created for Exfiltration | Thousands |
| Self-Hosted Runners Deployed by Attacker | Dozens+ (all named SHA1HULUD) |
The Attack Chain
The Initial Compromise: trojanized npm packages
- Attacker compromises npm maintainer accounts (phished/reused creds, weak tokens, etc.).
- They publish backdoored versions of legitimate packages from orgs like Zapier, ENS Domains, AsyncAPI, PostHog, and Postman (hundreds of packages, many with very high install counts).
- Compromised package.json includes a preinstall script that runs automatically on npm install.
The Loader: The preinstall script executes setup_bun.js, which:
- Checks if Bun is present; if not, downloads and installs it
- Adjusts PATH and locates the Bun binary
- Executes a huge, heavily-obfuscated payload bun_environment.js as a detached/background process, often outside the lifetime of the installer
The Core Payload: bun_environment.js (~480k lines, JS, heavily obfuscated) does the following:
- Credential harvesting
- Scan for secrets using TruffleHog-like logic
- Targets:
- Npm tokens, GitHub PATs, GitHub Actions runner tokens
- AWS, GCP, Azure credentials (environmental variables, config, IMDS)
- Exfiltration to GitHub
- Create attacker-controlled GitHub repos with random 18-char names whose description is consistently “Sha1-Hulud: The Second Coming.”
- Store secrets and telemetry in JSON files such as
- Cloud.json – grouped cloud credentials
- Contents.json – system info, GitHub account metadata, token used
- Environment.json – env variables snapshot
- truffleSecrets.json / actionsSecrets.json – secrets from local scans and GitHub Actions secrets, often double-Base64-encoded.
- GitHub & CI/CD Persistence + Remote Code Execution (RCE)
- Registers the host as a self-hosted runner named SHA1HULUD
- Injects malicious GitHub workflows, including:
- .github/workflows/discussion.yaml – runs on Discussions events and uses run: echo ${{ github.event.discussion.body }}, which is a command-injection backdoor: attacker puts shell commands into the Discussion body
- .github/workflows/formatter_*.yml (“Code Formatter”) – serializes all GitHub secrets to JSON and uploads them as workflow artifacts (e.g. format.json, later surfaced as actionsSecrets.json).
- Self-replication / worming
- Uses stolen npm tokens to enumerate packages owned by the maintainer and republish compromised versions embedding setup_bun.js and bun_environment.js.
- Use stolen GitHub access to:
- Create many exfil repos with “Sha1-Hulud: The Second Coming” description.
- Potentially inject malicious artifacts and workflows into other repos it can access.
- Destructive behavior & privilege escalation
- Wiper: If it cannot authenticate to GitHub, create repos, or find npm/GitHub tokens, it attempts to destroy the user’s home directory (Windows + Linux paths) using del/rd + cipher /W (Windows) and shred (Linux).
- Docker breakout: Attempts container → host escalation via a privileged Docker invocation like: docker run –rm –privileged -v /:/host ubuntu bash -c “cp /host/tmp/runner /host/etc/sudoers.d/runner” to gain passwordless root access.
Indicators of Compromise (IoCs)
As we are actively monitoring the situation and collecting more data, below is what we know that any affected organizations should hunt for.
- File-level IoCs:
- setup_bun.js
- bun_environment.js
- cloud.json
- environment.json
- truffleSecrets.json
- actionsSecrets.json
- CI/CD workflow IoCs:
- .github/workflows/discussion.yaml
- Contains github.event.discussion.body → RCE
- .github/workflows/formatter_*.yml
- Exfiltrates all GitHub secrets to artifact
- .github/workflows/discussion.yaml
- Code Repository IoCs
- Repos with description “Sha1-Hulud: The Second Coming”
- Random 18-character repository names
- Runner IoCs
- Self-hosted runner named SHA1HULUD
- Package IoCs
- Zapier ecosystems
- ENS Domains
- AsyncAPI
- PostHog
- Postman
- Many others
Incident Response Playbook for Shai-Hulud 2.0
Below is a compilation of a step-by-step IR playbook for any organizations suspected of being a victim of this attack. This sample playbook is optimized for organizations using GitHub, GitHub Actions, GitHub Enterprise, npm, and CI/CD pipelines affected by the SHA1-Hulud/Shai-Hulud 2.0 supply chain malware family.
Phase 1 – Identify
Initiate the response if ANY of the following are detected:
- Presence of malicious files
- setup_bun.js
- bun_environment.js
- cloud.json
- content.json
- environment.json
- truffleSecrets.json
- actionsSecret.json
- Suspicious GitHub workflows created or executed (see IoCs above or below)
- New unknown GitHub repos with description: “Sha1-Hulud: The Second Coming”
- Self-hosted GitHub runner named: SHA1HULUD
- npm packages with malicious preinstall lifecycle scripts
- CI logs showing unexpected Bun installation during npm install
Phase 2 – Investigation and Triage
For Cycode customers: Check the threat intelligence feeds. Detections for the Shai-hulud 2.0 IoCs in the form of our graph-based Risk Intelligence Queries (RIGs) were automatically created as detection policies.
2.1 Investigate Potential Exposure:
- Repositories:
- Any repo containing .github/workflows/discussion.yaml or formatter_*.yml
- Any repo installed or built with compromised npm packages
- Any repo accessed by compromised GitHub PATs
- Runners:
- All self-hosted runners
- Especially runners appearing recently or named SHA1HULUD
- Package Managers:
- All npm installations between Nov 21–24 2025
- Projects relying on AsyncAPI, Zapier, PostHog, ENS, or other known compromised package families
2.2 Validate Malware Presence:
- File Indicators
- Search for:
- Setup_bun.js
- Bun_environment.js
- Exfiltrated artifacts (cloud.json, etc – see phase 1)
- Search for:
- Workflow indicators
- Look for these workflows:
- .github/workflows/discussion.yaml (Contains run: echo ${{ github.event.discussion.body }} → RCE backdoor)
- formatter_*_*.yml (Collects all GitHub secrets → uploads artifact)
- Look for these workflows:
- GitHub Repo Metadata IoCs
- Repos created with:
- Random 18-char name
- Description Sha1-Hulud: The Second Coming
- Repos created with:
2.3 Validate Execution
- A system is compromised if ANY of the following occurred:
- Workflow artifacts containing org secrets (format.json, actionsSecrets.json)
- GitHub Discussion events causing workflow triggers
- npm scripts executed the malicious preinstall payload
- Bun runtime launched unexpectedly
- Outbound network egress from CI to GitHub API to attacker repos
2.4 Credential Exposure Analysis
- Check the following, if ANY token was accessible to the infected runner, assume it is compromised.
- GitHub Audit Logs
- GitHub API history
- Cloud IAM logs
- Secrets managers (unusual read events)
Phase 3 – Containment
- Perform the following actions immediately:
- Freeze risky repos, for impacted repos:
- Enable branch protection and block workflow changes
- Require PR reviews from SecOps / platform team
- Disable all suspicious self-hosted runners, especially SHA1HULUD, and as needed, review and pause any other recently created self-hosted runners
- Disable GitHub Actions org-wide temporarily if widespread compromise is suspected, or restrict to known-good repos only.
- Enforce org-wide GitHub account password resets
- Revoke all GitHub PATs and migrate to fine-grained PATs
- Block compromised npm packages via GitHub repository rulesets
- Snapshot for forensics, export:
- Copy of suspicious workflows
- Logs from recent CI runs (especially with Bun installs)
- GitHub audit logs for repo creation & workflow changes
- Freeze risky repos, for impacted repos:
Phase 4 – Eradication & Recovery
4.1 Sanitize Repositories
- Remove malicious workflow files
- Revert commits that added Bun-based scripts
- Rotate all secrets stored in:
- GitHub Secrets
- Npm registry tokens
- Cloud (AWS/GCP/Azure/etc) tokens
- CI/CD service account credentials
4.2 Rebuild CI Runners
- Reimage all self-hosted runners exposed during incident window
- Revoke and recreate runner registration tokens
- Switch to ephemeral runners where possible
4.3 Perform Hardening before Re-enabling GitHub Actions
- Block preinstall scripts in CI (policy)
- Enforce MFA and SSO for GitHub access
- Restrict workflow permissions (permissions: read-all)
- Disallow unreviewed workflow changes (enable branch protection)
Phase 5 – Post Incident
5.1 People
Conduct cross-functional post-mortem & lessons learned sessions. The cross-functional stakeholders should include leadership and representation from (Executive leadership, Engineering, DevOps, Office of CISO, Application/Product Security, Security Architecture, GRC, SOC).
Special considerations for SHA1-Hulud 2.0: Shai-Hulud 2.0 is not a normal outage, not a simple vulnerability exploit, and not a single-system compromise. It is a multi-system, multi-owner, multi-vector software supply chain infection that crosses:
- npm registry
- developer endpoints
- CI/CD pipelines
- GitHub repositories & workflows
- Cloud IAM
- Secrets management
- Organizational governance
A cross-functional post-mortem must reflect these complexities.
5.2 Process
Evaluate critical gaps, develop a remedial plan with cross-functional leadership endorsement and commitment, and update the playbook. This should also be done through cross-functional review board meetings with the same stakeholders as the post-mortem.
Conduct a Gap analysis to ensure you can prepare for future similar attacks. Below are unique considerations for Shai-Hulud 2.0 you should explicitly cover:
- npm Ecosystem & Dependency Sprawl Considerations
- Propagation through transitive dependencies
- Assess if the malware spread through: maintainer’s compromised packages, downstream dependency graphs, CI/CD cache reuse, and/or automatic version bump bots (Renovate, Dependabot)
- Gap analysis questions to ask:
- Was dependency pinning strict or loose?
- Did the org ingest preinstall-capable packages without scrutiny?
- How many services consumed auto-updated versions?
- Did Renovate/Dependabot unintentionally import compromised versions?
- SDLC Inventory and XBOM completeness
- Assess your organization’s visibility across the SDLC (repositories, ownership, commits, branches, workflows, configurations, dependencies) and what is contained in your software artifacts.
- Gap analysis questions to ask:
- Could we quickly identify every service consuming a malicious package?
- Did we rely on lockfiles? (if lockfiles are not enforced, you may run into conflicts that results in auto version updates in some cases)
- Did we produce built-time extended SBOMs for our apps in various forms such as containers, serverless, and others?
- Propagation through transitive dependencies
- CI/CD and GitHub Workflow Integrity
- This attack weaponized GitHub Actions themselves. Gap Analysis questions to ask:
- Workflow Governance Gaps
- Were workflow changes protected by CODEOWNERS?
- Could ANY developer commit workflow files?
- Did “formatter” and “discussion” workflows go unnoticed?
- GitHub Runner Trust Boundary
-
- Do we track all runner registrations?
- Are ephemeral or long-lived runners used?
- Are runners properly isolated (VM-per-job vs shared host)?
- Are GitHub runner tokens rotated?
-
- Overly Broad Workflow Permissions
- Are permissions: write-all?
- Do we default to broad org-level permissions?
- Additional gap analysis questions to ask:
- Did we ever audit our workflow permissions?
- Were secrets accessible to workflows that didn’t need them?
- Did we unknowingly allow workflows to read all org secrets?
- Secrets Exfiltration & Identity Access
- Shai-Hulud data shows 14,206 secrets exposed, with 2,485 still valid during review. The impact isn’t limited to GitHub. Secrets stolen from GitHub were used to pivot into:
- AWS (373 keys)
- GCP (300 keys)
- Azure (115 keys)
- npm tokens
- local developer environments
- Gap analysis questions to ask:
- Do we know which secrets were moved cross-cloud?
- Did we have centralized secret revocation?
- If secret rotation took days, ask:
- Why?
- Which parts were manual?
- Which tool(s) failed to detect secret misuse?
- Was MFA enforced for GitHub (including FIDO2)?
- Shai-Hulud data shows 14,206 secrets exposed, with 2,485 still valid during review. The impact isn’t limited to GitHub. Secrets stolen from GitHub were used to pivot into:
- Developer Endpoint Exposure
- Because Shai-Hulud ran during npm install, it infected developer laptops.
- Gap analysis questions to ask:
- Do we have endpoint detection on developer machines?
- Did EDR detect Bun runtime execution
- Did developers run infected packages locally?
- Were home directories compromised by wiper behavior?
- Do engineers have local secrets stored unencrypted? This attack actively searched: ~/.aws, ~/.npmrc, ~/.config/gcloud, and ~/.ssh
- If any developer had plaintext credentials, leadership must address policy gaps.
- Do we have endpoint detection on developer machines?
- Organization-wide GitHub Exposure
- Shai-Hulud 2.0 created thousands of repos for exfiltration.
- Gap analysis questions to ask:
- Do we monitor org-wide repo creation?
- Did SOC alert on sudden repo creation spikes?
- Do we tag repos with owners?
- Did any repos get created that no one noticed?
- Do we have active monitoring/detections for suspicious/anomaly workflows such as:
- github.event.discussion.body
- workflows named “formatter_*”
- runs-on: self-hosted with unknown labels
- Do we monitor org-wide repo creation?
- Leadership and Communication Considerations
- Cross Functional Multi-team alignment
- Because multiple systems were hit, leadership needs to ask:
- Did each team understand the severity early?
- Was the blast radius communicated effectively?
- Was there confusion about who owns secrets rotation?
- Was AppSec or DevOps the bottleneck?
- Did Legal and Comms have accurate info for messaging?
- Executive Reporting Clarity. Can you respond to the following
- What is the business impact?
- What is the customer exposure?
- What are the regulatory implications?
- What is the timeline to full recovery?
- Are we still compromised?
- Updates to Threat Modeling
- If threat modeling has not been a focused priority, this incident could be a great opportunity to re-evaluate. If threat modelling has been a priority, this incident is a great time to update some common assumptions.
- Common Engineering assumptions:
- “Dependencies are safe by default” – false
- “CI/CD is internal infrastructure” – false
- “GitHub Actions are low risk” – false
- “Runner hosts are trusted and persistent” – false
- It is just dev environment, “Cloud credentials never leave CI environment” – false (exfiltration confirmed)
- Shai-Hulud 2.0 should be used as a trigger to redesign trust boundaries.
- Permanent Preventative Actions to Assign (Update RACI matrix)
- Enforce CODEOWNERS + protected workflows → No workflow changes without proper approval
- Mandatory GitHub OIDC for cloud access → Eliminate cloud access keys entirely
- Ephemeral isolated CI runners → Each job = fresh container/VM
- Registry & dependency governance policy → Block unknown maintainers & lifecycle scripts
- Mandatory SBOM generation and artifact attestation → Every build, every dependency
- Continuous secret scanning + immediate auto-revocation → No human delay
- Special strategy/architecture/configuration considerations for Each Team
- Engineering/Dev Teams
- Pin dependencies
- Avoid package with lifecycle scripts
- Increase test coverage around dependency changes
- DevOps
- Restrict preinstall, postinstall in CI
- Enforce ephemeral runners
- Lock down workflow permissions
- Application/Product Security
- Add policy for dependency trust and review
- Build detection rules for workflows
- Integrate malicious package threat intelligence feeds
- SOC
- Add detections and playbook for:
- Unknown runner registration
- Sudden repo creation
- Secrets exfil patterns
- Bun runtime execution
- Add detections and playbook for:
- Executive Leadership
- Budget for CI/CD security & hardening (both tools and operating resources)
- Approve organization-wide MFA/FIDO2 enforcement
- Sponsor post-incident modernization projects specific to software supply chain security.
- Engineering/Dev Teams
5.3 Technology
- Conduct tools rationalization and evaluation to determine whether you have all the capabilities covered for software supply chain security capable of detecting and responding to this attack. At a minimum, the tool should have the following core capabilities:
- Inventory the entire SDLC technology and configurations (repos, projects, code owners, commits, branches, build workflows, artifacts, dependencies, configurations, access permissions)
- Map, visualize, and correlate discovered assets for risk detection
- Secrets detection and validation across SDLC (code, build workflows, ticketing, collaboration, etc)
- Secrets Management
- SBOM Management (Import & export)
- CI/CD Security (detect repo, pipeline misconfigurations)
- Monitor public and private leaked code repositories
- Application Security Testing (SCA specifically, SAST, Container, IaC, etc)
- Risk correlation engine that could contextualize vulnerabilities and IoCs across different layers for complex attacks like Shai-Hulud 2.0
- Graph-based query engine to write custom detection rules and policies
- Runtime monitoring of build workflows for anomalies
Note: Cycode is the complete platform with all of the above capabilities.
- Build detection rules to check against the IoCs mentioned above
- Conduct post-remediation scans:
- Scan for all the SHAI-HULUD IoCs
- Secrets scanning across repos, workflows, ticketing, collaboration, chat
- GitHub Audit Log analysis
- Confirm the following:
- No SHA1HULUD self-hosted runners remain
- No rogue repos with malicious descriptions
- No remaining malicious workflows
