TL;DR

This is the second time a malicious campaign – codenamed Shai‑Hulud – has been detected targeting the npm ecosystem. The first campaign covered in this blog revealed how threat-actors trojanised trusted libraries. 

In this current wave:

  • Attackers published trojanised versions of trusted packages that execute during install (via a post-install or pre-install hook) to harvest credentials such as developer tokens, CI/CD secrets, and cloud metadata (AWS, GCP, Azure).
  • They also established persistence by injecting malicious workflows and connectors: e.g., creating branches named “shai-hulud”, dropping GitHub Actions workflows, uploading stolen data to repositories named “Shai-Hulud”.
  • The campaign exhibits worm-like propagation: once a maintainer’s token is compromised, the malware uses it to republish other packages owned by that maintainer – enabling lateral spread across the npm registry.

What happened?

  • The campaign abuses compromised maintainer accounts to publish legitimate-looking npm packages. While this builds on earlier activity, the new wave introduces pre-install lifecycle execution of malicious scripts, dramatically raising the risk.
  • During installation, payload files (e.g., setup_bun.js, bun_environment.js) are dropped.
  • It then registers a self-hosted GitHub Actions runner named “SHA1HULUD” in the compromised repository.
  • A workflow .github/workflows/discussion.yaml is added which triggers on GitHub Discussions and executes on the self-hosted runner, enabling arbitrary commands.
  • Another workflow .github/workflows/formatter_123456789.yml is pushed which enumerates GitHub secrets, uploads them as an artifact, downloads the artifact, then deletes the branch/workflow to cover tracks.
  • The attacker creates files such as cloud.json, contents.json, environment.json, truffleSecrets.json during the install stage, and supports Linux, Windows, and macOS runners.
  • Over 25,000 repositories across ~350 unique users were identified as affected. Currently, 26.3k repositories are exposed due to the malware.
  • In some bursts ~1,000 new repos were being added every 30 minutes.
  • Attacker Errors: A number of packages that were spread via the community contained only the initial staging code (setup_bun.js) and were missing the main worm (bun_environment.js). This mistake appears to have limited the overall impact of the attack.

Compromised Packages and TTPs

Compromised Packages: A total of 425 compromised packages have been detected with an estimated 132 million monthly downloads. They span major namespaces, including those for Zapier (e.g., @zapier/zapier-sdk (0.15.5–0.15.7), zapier-platform-core (18.0.2–18.0.4)), ENS Domains (@ensdomains/ens-validation 0.1.1), @posthog/agent 1.24.1, and many under @trigo/* and @orbitgtbelgium/*. See appendix for a detailed list.

TTPs Recorded:

TacticTechnique IDTechnique NameUse in This Campaign
Initial AccessT1584Compromise Supply Chain: Software Dependencymalicious npm package versions.
ExecutionT1059.004Command and Scripting Interpreter: Unix Shellpre-install script in package.json.
PersistenceT1136Create AccountGitHub Actions workflow and self-hosted runner “Shai-Hulud”.
DiscoveryT1580Cloud Infrastructure DiscoveryAccess to cloud metadata endpoints (AWS/GCP/Azure).
CollectionT1005Data from Local SystemData files containing encoded secrets (e.g., format.json).
ExfiltrationT1041Exfiltration Over C2 ChannelOutbound connection to webhook[.]site, creation of GitHub repos named ‘Shai-Hulud’, with new secrets published to repositories using the description “Sha1-Hulud: The Second Coming.”

Timeline

The initial compromises were detected on 24/11/2025:

  • 3:16:26 AM GMT+0: The first packages compromised were go-template and 36 packages from AsyncAPI.
  • 4:11:55 AM GMT+0: Compromise of PostHog packages began.
  • 5:09:25 AM GMT+0: Compromise of Postman packages began.

What should organisations do?

  • Remove and replace compromised packages: Clear npm cache (npm cache clean –force), delete node_modules, rebuild from clean dependencies, and pin to versions prior to November 21, 2025.
  • Rotate credentials: Revoke/regenerate npm publishing tokens, GitHub personal access tokens, SSH keys, cloud provider credentials (AWS/GCP/Azure). Enforce phishing-resistant MFA.
  • Audit GitHub and CI/CD infrastructure: Search for repositories or branches with names referencing “Shai-Hulud”, review for unauthorized workflows or self-hosted runners, examine recent package publishes in your org.
  • Harden pipelines: Disable or limit install-time scripts (preinstall/postinstall) if possible, restrict build-node egress to trusted domains, use least-privilege tokens for automation.

How Orca can help

Orca offers a unified and comprehensive cloud security platform that identifies, prioritizes, and remediates security risks and compliance issues across AWS, Azure, Google Cloud, Oracle Cloud, Alibaba Cloud, and Kubernetes. The Orca Cloud Security Platform leverages Orca’s patented SideScanning™ technology to provide complete coverage and comprehensive risk detection.

Additionally, Orca provides:

  • Data Security Posture Management (DSPM): Orca provides DSPM capabilities that helps organizations secure their sensitive data. Orca can help you quickly identify which secrets are present in your environment and where, simplifying and accelerating the process of understanding which secrets were exposed in case of a known attack, and general management of sensitive information day-to-day.
  • Inventory: Orca tracks all your cloud assets and identities across your cloud estate, including users, services, and packages. In an attack such as this one, we can help you quickly discover which systems are compromised and help you maintain the incident as fast as possible.
  • Exposure management: Even if you accidentally downloaded a malicious npm version, it is not as scary as it could have been if your system does not have any outgoing network permitted. With correct identification of relevant systems you can effectively prioritize how to best detain the situation.

Learn more

Interested in learning more about the Orca Platform? Schedule your personalized 1:1 demo.

Appendix: Full List of Affected Packages

  • @accordproject/concerto-analysis
  • @accordproject/markdown-docx
  • @accordproject/markdown-it-cicero
  • @actbase/css-to-react-native-transform
  • @actbase/native
  • @actbase/node-server
  • @actbase/react-absolute
  • @actbase/react-daum-postcode
  • @actbase/react-kakaosdk
  • @actbase/react-native-actionsheet
  • @actbase/react-native-devtools
  • @actbase/react-native-fast-image
  • @actbase/react-native-kakao-channel
  • @actbase/react-native-kakao-navi
  • @actbase/react-native-less-transformer
  • @actbase/react-native-naver-login
  • @actbase/react-native-simple-video
  • @actbase/react-native-tiktok
  • @alexcolls/nuxt-socket.io
  • @alexcolls/nuxt-ux
  • @aryanhussain/my-angular-lib
  • @asyncapi/avro-schema-parser
  • @asyncapi/bundler
  • @asyncapi/cli
  • @asyncapi/converter
  • @asyncapi/diff
  • @asyncapi/dotnet-rabbitmq-template
  • @asyncapi/edavisualiser
  • @asyncapi/generator
  • @asyncapi/generator-components
  • @asyncapi/generator-helpers
  • @asyncapi/generator-react-sdk
  • @asyncapi/go-watermill-template
  • @asyncapi/html-template
  • @asyncapi/java-spring-cloud-stream-template
  • @asyncapi/java-spring-template
  • @asyncapi/java-template
  • @asyncapi/keeper
  • @asyncapi/markdown-template
  • @asyncapi/modelina
  • @asyncapi/modelina-cli
  • @asyncapi/multi-parser
  • @asyncapi/nodejs-template
  • @asyncapi/nodejs-ws-template
  • @asyncapi/nunjucks-filters
  • @asyncapi/openapi-schema-parser
  • @asyncapi/optimizer
  • @asyncapi/parser
  • @asyncapi/php-template
  • @asyncapi/problem
  • @asyncapi/protobuf-schema-parser
  • @asyncapi/python-paho-template
  • @asyncapi/react-component
  • @asyncapi/server-api
  • @asyncapi/specs
  • @asyncapi/studio
  • @asyncapi/web-component
  • @caretive/caret-cli
  • @clausehq/flows-step-jsontoxml
  • @clausehq/flows-step-sendgridemail
  • @commute/bloom
  • @commute/market-data
  • @dev-blinq/ai-qa-logic
  • @dev-blinq/cucumber_client
  • @ensdomains/address-encoder
  • @ensdomains/blacklist
  • @ensdomains/buffer
  • @ensdomains/ccip-read-cf-worker
  • @ensdomains/ccip-read-dns-gateway
  • @ensdomains/ccip-read-router
  • @ensdomains/ccip-read-worker-viem
  • @ensdomains/content-hash
  • @ensdomains/curvearithmetics
  • @ensdomains/cypress-metamask
  • @ensdomains/dnsprovejs
  • @ensdomains/dnssec-oracle-anchors
  • @ensdomains/dnssecoraclejs
  • @ensdomains/durin
  • @ensdomains/durin-middleware
  • @ensdomains/ens-archived-contracts
  • @ensdomains/ens-avatar
  • @ensdomains/ens-contracts
  • @ensdomains/ensjs
  • @ensdomains/ensjs-react
  • @ensdomains/ens-test-env
  • @ensdomains/ens-validation
  • @ensdomains/eth-ens-namehash
  • @ensdomains/hackathon-registrar
  • @ensdomains/hardhat-chai-matchers-viem
  • @ensdomains/hardhat-toolbox-viem-extended
  • @ensdomains/mock
  • @ensdomains/name-wrapper
  • @ensdomains/offchain-resolver-contracts
  • @ensdomains/op-resolver-contracts
  • @ensdomains/react-ens-address
  • @ensdomains/renewal
  • @ensdomains/renewal-widget
  • @ensdomains/reverse-records
  • @ensdomains/server-analytics
  • @ensdomains/solsha1
  • @ensdomains/subdomain-registrar
  • @ensdomains/test-utils
  • @ensdomains/thorin
  • @ensdomains/ui
  • @ensdomains/unicode-confusables
  • @ensdomains/unruggable-gateways
  • @ensdomains/vite-plugin-i18next-loader
  • @ensdomains/web3modal
  • @everreal/web-analytics
  • @fishingbooker/browser-sync-plugin
  • @fishingbooker/react-swiper
  • @hapheus/n8n-nodes-pgp
  • @ifelsedeveloper/protocol-contracts-svm-idl
  • @ifings/design-system
  • @kvytech/cli
  • @kvytech/components
  • @kvytech/habbit-e2e-test
  • @kvytech/medusa-plugin-announcement
  • @kvytech/medusa-plugin-management
  • @kvytech/medusa-plugin-newsletter
  • @kvytech/medusa-plugin-product-reviews
  • @kvytech/medusa-plugin-promotion
  • @kvytech/web
  • @lessondesk/api-client
  • @lessondesk/babel-preset
  • @lessondesk/eslint-config
  • @lessondesk/schoolbus
  • @louisle2/core
  • @louisle2/cortex-js
  • @lpdjs/firestore-repo-service
  • @markvivanco/app-version-checker
  • @mcp-use/cli
  • @mcp-use/inspector
  • @mcp-use/mcp-use
  • @mparpaillon/connector-parse
  • @mparpaillon/imagesloaded
  • @orbitgtbelgium/mapbox-gl-draw-cut-polygon-mode
  • @orbitgtbelgium/mapbox-gl-draw-scale-rotate-mode
  • @orbitgtbelgium/orbit-components
  • @orbitgtbelgium/time-slider
  • @osmanekrem/error-handler
  • @posthog/agent
  • @posthog/ai
  • @posthog/automatic-cohorts-plugin
  • @posthog/bitbucket-release-tracker
  • @posthog/cli
  • @posthog/clickhouse
  • @posthog/core
  • @posthog/currency-normalization-plugin
  • @posthog/customerio-plugin
  • @posthog/databricks-plugin
  • @posthog/drop-events-on-property-plugin
  • @posthog/event-sequence-timer-plugin
  • @posthog/filter-out-plugin
  • @posthog/first-time-event-tracker
  • @posthog/geoip-plugin
  • @posthog/github-release-tracking-plugin
  • @posthog/gitub-star-sync-plugin
  • @posthog/heartbeat-plugin
  • @posthog/hedgehog-mode
  • @posthog/icons
  • @posthog/ingestion-alert-plugin
  • @posthog/intercom-plugin
  • @posthog/kinesis-plugin
  • @posthog/laudspeaker-plugin
  • @posthog/lemon-ui
  • @posthog/maxmind-plugin
  • @posthog/migrator3000-plugin
  • @posthog/netdata-event-processing
  • @posthog/nextjs
  • @posthog/nextjs-config
  • @posthog/nuxt
  • @posthog/pagerduty-plugin
  • @posthog/piscina
  • @posthog/plugin-contrib
  • @posthog/plugin-server
  • @posthog/plugin-unduplicates
  • @posthog/postgres-plugin
  • @posthog/react-rrweb-player
  • @posthog/rrdom
  • @posthog/rrweb
  • @posthog/rrweb-player
  • @posthog/rrweb-record
  • @posthog/rrweb-replay
  • @posthog/rrweb-snapshot
  • @posthog/rrweb-utils
  • @posthog/sendgrid-plugin
  • @posthog/siphash
  • @posthog/snowflake-export-plugin
  • @posthog/taxonomy-plugin
  • @posthog/twilio-plugin
  • @posthog/twitter-followers-plugin
  • @posthog/url-normalizer-plugin
  • @posthog/variance-plugin
  • @posthog/web-dev-server
  • @posthog/wizard
  • @posthog/zendesk-plugin
  • @postman/aether-icons
  • @postman/csv-parse
  • @postman/final-node-keytar
  • @postman/mcp-ui-client
  • @postman/node-keytar
  • @postman/pm-bin-linux-x64
  • @postman/pm-bin-macos-arm64
  • @postman/pm-bin-macos-x64
  • @postman/pm-bin-windows-x64
  • @postman/postman-collection-fork
  • @postman/postman-mcp-cli
  • @postman/postman-mcp-server
  • @postman/pretty-ms
  • @postman/secret-scanner-wasm
  • @postman/tunnel-agent
  • @postman/wdio-allure-reporter
  • @postman/wdio-junit-reporter
  • @quick-start-soft/quick-document-translator
  • @quick-start-soft/quick-git-clean-markdown
  • @quick-start-soft/quick-markdown
  • @quick-start-soft/quick-markdown-compose
  • @quick-start-soft/quick-markdown-image
  • @quick-start-soft/quick-markdown-print
  • @quick-start-soft/quick-markdown-translator
  • @quick-start-soft/quick-remove-image-background
  • @quick-start-soft/quick-task-refine
  • @seung-ju/next
  • @seung-ju/openapi-generator
  • @seung-ju/react-hooks
  • @seung-ju/react-native-action-sheet
  • @strapbuild/react-native-date-time-picker
  • @strapbuild/react-native-perspective-image-cropper
  • @strapbuild/react-native-perspective-image-cropper-2
  • @strapbuild/react-native-perspective-image-cropper-poojan31
  • @thedelta/eslint-config
  • @tiaanduplessis/json
  • @tiaanduplessis/react-progressbar
  • @trefox/sleekshop-js
  • @trigo/atrix
  • @trigo/atrix-acl
  • @trigo/atrix-elasticsearch
  • @trigo/atrix-mongoose
  • @trigo/atrix-orientdb
  • @trigo/atrix-postgres
  • @trigo/atrix-pubsub
  • @trigo/atrix-redis
  • @trigo/atrix-soap
  • @trigo/atrix-swagger
  • @trigo/bool-expressions
  • @trigo/eslint-config-trigo
  • @trigo/fsm
  • @trigo/hapi-auth-signedlink
  • @trigo/jsdt
  • @trigo/keycloak-api
  • @trigo/node-soap
  • @trigo/pathfinder-ui-css
  • @trigo/trigo-hapijs
  • @varsityvibe/api-client
  • @varsityvibe/validation-schemas
  • @zapier/ai-actions
  • @zapier/ai-actions-react
  • @zapier/babel-preset-zapier
  • @zapier/browserslist-config-zapier
  • @zapier/eslint-plugin-zapier
  • @zapier/mcp-integration
  • @zapier/secret-scrubber
  • @zapier/spectral-api-ruleset
  • @zapier/stubtree
  • @zapier/zapier-sdk
  • asyncapi-preview
  • atrix
  • atrix-mongoose
  • axios-builder
  • axios-cancelable
  • axios-timed
  • barebones-css
  • blinqio-executions-cli
  • bool-expressions
  • bun-plugin-httpfile
  • bytecode-checker-cli
  • bytes-to-x
  • calc-loan-interest
  • capacitor-plugin-apptrackingios
  • capacitor-plugin-purchase
  • capacitor-plugin-scgssigninwithgoogle
  • capacitor-purchase-history
  • capacitor-voice-recorder-wav
  • chrome-extension-downloads
  • claude-token-updater
  • coinmarketcap-api
  • command-irail
  • compare-obj
  • count-it-down
  • cpu-instructions
  • create-glee-app
  • create-hardhat3-app
  • create-mcp-use-app
  • crypto-addr-codec
  • designstudiouiux
  • devstart-cli
  • discord-bot-server
  • dotnet-template
  • drop-events-on-property-plugin
  • enforce-branch-name
  • eslint-config-trigo
  • eslint-config-zeallat-base
  • ethereum-ens
  • evm-checkcode-cli
  • exact-ticker
  • expo-audio-session
  • feature-flip
  • fittxt
  • flapstacks
  • flatten-unflatten
  • formik-error-focus
  • formik-store
  • fuzzy-finder
  • gate-evm-check-code2
  • gate-evm-tools-test
  • gatsby-plugin-cname
  • get-them-args
  • github-action-for-generator
  • gitsafe
  • go-template
  • haufe-axera-api-client
  • hopedraw
  • hope-mapboxdraw
  • hyperterm-hipster
  • image-to-uri
  • invo
  • iron-shield-miniapp
  • ito-button
  • itobuz-angular
  • itobuz-angular-auth
  • jacob-zuma
  • jan-browser
  • jquery-bindings
  • just-toasty
  • kill-port
  • korea-administrative-area-geo-json-util
  • license-o-matic
  • lint-staged-imagemin
  • lite-serper-mcp-server
  • luno-api
  • manual-billing-system-miniapp-api
  • mcp-use
  • medusa-plugin-announcement
  • medusa-plugin-logs
  • medusa-plugin-momo
  • medusa-plugin-product-reviews-kvy
  • medusa-plugin-zalopay
  • mon-package-react-typescript
  • n8n-nodes-tmdb
  • nanoreset
  • next-circular-dependency
  • obj-to-css
  • okta-react-router-6
  • open2internet
  • orbit-boxicons
  • orbit-nebula-draw-tools
  • orbit-nebula-editor
  • orbit-soap
  • parcel-plugin-asset-copier
  • piclite
  • pico-uid
  • poper-react-sdk
  • posthog-docusaurus
  • posthog-js
  • posthog-node
  • posthog-plugin-hello-world
  • posthog-react-native
  • posthog-react-native-session-replay
  • ra-data-firebase
  • react-component-taggers
  • react-element-prompt-inspector
  • react-jam-icons
  • react-keycloak-context
  • react-library-setup
  • react-native-datepicker-modal
  • react-native-email
  • react-native-fetch
  • react-native-get-pixel-dimensions
  • react-native-jam-icons
  • react-native-log-level
  • react-native-phone-call
  • react-native-retriable-fetch
  • react-native-use-modal
  • react-native-view-finder
  • react-native-websocket
  • react-native-worklet-functions
  • react-qr-image
  • redux-forge
  • redux-router-kit
  • sa-company-registration-number-regex
  • sa-id-gen
  • scgs-capacitor-subscribe
  • scgsffcreator
  • set-nested-prop
  • shell-exec
  • shinhan-limit-scrap
  • skills-use
  • sort-by-distance
  • stoor
  • svelte-autocomplete-select
  • tcsp-draw-test
  • tenacious-fetch
  • test23112222-api
  • test-foundry-app
  • test-hardhat-app
  • token.js-fork
  • trigo-react-app
  • typeorm-orbit
  • undefsafe-typed
  • uplandui
  • url-encode-decode
  • vite-plugin-httpfile
  • web-types-htmx
  • web-types-lit
  • wenk
  • zapier-async-storage
  • zapier-platform-cli
  • zapier-platform-core
  • zapier-platform-legacy-scripting-runner
  • zapier-platform-schema
  • zapier-scripts
  • zuper-cli
  • zuper-sdk
  • zuper-stream