Feed
CriticalPublished 15 Sept 2025197 packages · 509 versions

Original Shai-Hulud npm worm

Summary

First successful self-propagating worm in the npm ecosystem. Downstream of the August 2025 s1ngularity/Nx GitHub-token theft. The postinstall hook ran TruffleHog to harvest secrets, opened public GitHub repos named "Shai-Hulud" to publish them, force-converted private repos to public with a "-migration" suffix, and used stolen npm tokens to publish malicious versions of any package the maintainer could access. ~180 unique packages compromised across 300+ versions, including CrowdStrike's own scope (@crowdstrike/*).

worminfostealercredential-theftaccount-takeovermaintainer-takeover
Detected by
StepSecurity · Socket · Aikido · Wiz
Also known as
Shai-Hulud · s1ngularity downstream
Ecosystems
npm
Packages tracked
197

What happened

Shai-Hulud is the first publicly-confirmed self-propagating worm in the npm ecosystem. It descends directly from the August 2025 s1ngularity / Nx GitHub-token theft: a researcher leaked Personal Access Tokens from contributors to the nrwl/nx repo, and those tokens were used a month later to seed the worm into reachable maintainer accounts.

The payload runs from a postinstall hook. It uses TruffleHog to scan the host for any credentials it can find — npm tokens, GitHub PATs, AWS/GCP/Azure keys, anything matching a known secret pattern — then performs three propagation moves: it creates a public GitHub repo named "Shai-Hulud" containing the stolen secrets, force-converts private repos belonging to the victim to public with a -migration suffix, and uses the stolen npm tokens to push new malicious versions of every package the maintainer can publish to.

Around 180 unique packages were compromised across 300+ versions before npm and GitHub coordinated takedowns. High-blast-radius hits included @ctrl/tinycolor, ngx-bootstrap, ngx-toastr, and — notably — the entire @crowdstrike/* scope, which forced an internal incident response at CrowdStrike. The worm continued to surface in mini-revivals through early 2026 (see multi-2026-04-30-mini-shai-hulud-wave2 and npm-2026-05-shai-hulud-tanstack).

If you built anything against an affected package between September 15 and 18, 2025, treat the host as credential-compromised: rotate every secret reachable from that environment, then audit the GitHub org for unexpected public repos and -migration twins.

Affected packages (197)

  • npm@ahmedhfarag/ngx-perfect-scrollbar
    20.0.20
  • npm@ahmedhfarag/ngx-virtual-scroller
    4.0.4
  • npm@art-ws/common
    2.0.28
  • npm@art-ws/config-eslint
    2.0.42.0.5
  • npm@art-ws/config-ts
    2.0.72.0.8
  • npm@art-ws/db-context
    2.0.24
  • npm@art-ws/di
    2.0.282.0.32
  • npm@art-ws/di-node
    2.0.13
  • npm@art-ws/eslint
    1.0.51.0.6
  • npm@art-ws/fastify-http-server
    2.0.242.0.27
  • npm@art-ws/http-server
    2.0.212.0.25
  • npm@art-ws/openapi
    0.1.90.1.12
  • npm@art-ws/package-base
    1.0.51.0.6
  • npm@art-ws/prettier
    1.0.51.0.6
  • npm@art-ws/slf
    2.0.152.0.22
  • npm@art-ws/ssl-info
    1.0.91.0.10
  • npm@art-ws/web-app
    1.0.31.0.4
  • npm@basic-ui-components-stc/basic-ui-components
    1.0.5
  • npm@crowdstrike/commitlint
    8.1.18.1.2
  • npm@crowdstrike/falcon-shoelace
    0.4.10.4.2
  • npm@crowdstrike/foundry-js
    0.19.10.19.2
  • npm@crowdstrike/glide-core
    0.34.20.34.3
  • npm@crowdstrike/logscale-dashboard
    1.205.11.205.2
  • npm@crowdstrike/logscale-file-editor
    1.205.11.205.2
  • npm@crowdstrike/logscale-parser-edit
    1.205.11.205.2
  • npm@crowdstrike/logscale-search
    1.205.11.205.2
  • npm@crowdstrike/tailwind-toucan-base
    5.0.15.0.2
  • npm@ctrl/deluge
    7.2.17.2.2
  • npm@ctrl/golang-template
    1.4.21.4.3
  • npm@ctrl/magnet-link
    4.0.34.0.4
  • npm@ctrl/ngx-codemirror
    7.0.17.0.2
  • npm@ctrl/ngx-csv
    6.0.16.0.2
  • npm@ctrl/ngx-emoji-mart
    9.2.19.2.2
  • npm@ctrl/ngx-rightclick
    4.0.14.0.2
  • npm@ctrl/qbittorrent
    9.7.19.7.2
  • npm@ctrl/react-adsense
    2.0.12.0.2
  • npm@ctrl/shared-torrent
    6.3.16.3.2
  • npm@ctrl/tinycolor
    4.1.14.1.2
  • npm@ctrl/torrent-file
    4.1.14.1.2
  • npm@ctrl/transmission
    7.3.1
  • npm@ctrl/ts-base32
    4.0.14.0.2
  • npm@hestjs/core
    0.2.1
  • npm@hestjs/cqrs
    0.1.6
  • npm@hestjs/demo
    0.1.2
  • npm@hestjs/eslint-config
    0.1.2
  • npm@hestjs/logger
    0.1.6
  • npm@hestjs/scalar
    0.1.7
  • npm@hestjs/validation
    0.1.6
  • npm@nativescript-community/arraybuffers
    1.1.61.1.71.1.8
  • npm@nativescript-community/gesturehandler
    2.0.35
  • npm@nativescript-community/perms
    3.0.53.0.63.0.73.0.83.0.9
  • npm@nativescript-community/sentry
    4.6.43
  • npm@nativescript-community/sqlite
    3.5.23.5.33.5.43.5.5
  • npm@nativescript-community/text
    1.6.91.6.101.6.111.6.121.6.13
  • npm@nativescript-community/typeorm
    0.2.300.2.310.2.320.2.33
  • npm@nativescript-community/ui-collectionview
    6.0.6
  • npm@nativescript-community/ui-document-picker
    1.1.271.1.2813.0.32
  • npm@nativescript-community/ui-drawer
    0.1.30
  • npm@nativescript-community/ui-image
    4.5.6
  • npm@nativescript-community/ui-label
    1.3.351.3.361.3.37
  • npm@nativescript-community/ui-material-bottom-navigation
    7.2.727.2.737.2.747.2.75
  • npm@nativescript-community/ui-material-bottomsheet
    7.2.72
  • npm@nativescript-community/ui-material-core
    7.2.727.2.737.2.747.2.757.2.76
  • npm@nativescript-community/ui-material-core-tabs
    7.2.727.2.737.2.747.2.757.2.76
  • npm@nativescript-community/ui-material-ripple
    7.2.727.2.737.2.747.2.75
  • npm@nativescript-community/ui-material-tabs
    7.2.727.2.737.2.747.2.75
  • npm@nativescript-community/ui-pager
    14.1.3614.1.3714.1.38
  • npm@nativescript-community/ui-pulltorefresh
    2.5.42.5.52.5.62.5.7
  • npm@nexe/config-manager
    0.1.1
  • npm@nexe/eslint-config
    0.1.1
  • npm@nexe/logger
    0.1.3
  • npm@nstudio/angular
    20.0.420.0.520.0.6
  • npm@nstudio/focus
    20.0.420.0.520.0.6
  • npm@nstudio/nativescript-checkbox
    2.0.62.0.72.0.82.0.9
  • npm@nstudio/nativescript-loading-indicator
    5.0.15.0.25.0.35.0.4
  • npm@nstudio/ui-collectionview
    5.1.115.1.125.1.135.1.14
  • npm@nstudio/web
    20.0.4
  • npm@nstudio/web-angular
    20.0.4
  • npm@nstudio/xplat
    20.0.520.0.620.0.7
  • npm@nstudio/xplat-utils
    20.0.520.0.620.0.7
  • npm@operato/board
    9.0.369.0.379.0.389.0.399.0.409.0.419.0.429.0.439.0.449.0.459.0.46
  • npm@operato/data-grist
    9.0.299.0.359.0.369.0.37
  • npm@operato/graphql
    9.0.229.0.359.0.369.0.379.0.389.0.399.0.409.0.419.0.429.0.439.0.449.0.459.0.46
  • npm@operato/headroom
    9.0.29.0.359.0.369.0.37
  • npm@operato/help
    9.0.359.0.369.0.379.0.389.0.399.0.409.0.419.0.429.0.439.0.449.0.459.0.46
  • npm@operato/i18n
    9.0.359.0.369.0.37
  • npm@operato/input
    9.0.279.0.359.0.369.0.379.0.389.0.399.0.409.0.419.0.429.0.439.0.449.0.459.0.469.0.479.0.48
  • npm@operato/layout
    9.0.359.0.369.0.37
  • npm@operato/popup
    9.0.229.0.359.0.369.0.379.0.389.0.399.0.409.0.419.0.429.0.439.0.449.0.459.0.469.0.49
  • npm@operato/pull-to-refresh
    9.0.369.0.379.0.389.0.399.0.409.0.419.0.42
  • npm@operato/shell
    9.0.229.0.359.0.369.0.379.0.389.0.39
  • npm@operato/styles
    9.0.29.0.359.0.369.0.37
  • npm@operato/utils
    9.0.229.0.359.0.369.0.379.0.389.0.399.0.409.0.419.0.429.0.439.0.449.0.459.0.469.0.49
  • npm@teselagen/bio-parsers
    0.4.290.4.30
  • npm@teselagen/bounce-loader
    0.3.160.3.17
  • npm@teselagen/file-utils
    0.3.210.3.22
  • npm@teselagen/liquibase-tools
    0.4.1
  • npm@teselagen/ove
    0.7.390.7.40
  • npm@teselagen/range-utils
    0.3.140.3.15
  • npm@teselagen/react-list
    0.8.190.8.20
  • npm@teselagen/react-table
    6.10.196.10.206.10.216.10.22
  • npm@teselagen/sequence-utils
    0.3.330.3.34
  • npm@teselagen/ui
    0.9.90.9.10
  • npm@thangved/callback-window
    1.1.4
  • npm@things-factory/attachment-base
    9.0.429.0.439.0.449.0.459.0.469.0.479.0.489.0.499.0.509.0.519.0.529.0.539.0.549.0.55
  • npm@things-factory/auth-base
    9.0.429.0.439.0.449.0.45
  • npm@things-factory/email-base
    9.0.429.0.439.0.449.0.459.0.469.0.479.0.489.0.499.0.509.0.519.0.529.0.539.0.549.0.559.0.569.0.579.0.589.0.59
  • npm@things-factory/env
    9.0.429.0.439.0.449.0.45
  • npm@things-factory/integration-base
    9.0.429.0.439.0.449.0.45
  • npm@things-factory/integration-marketplace
    9.0.429.0.439.0.449.0.45
  • npm@things-factory/shell
    9.0.429.0.439.0.449.0.45
  • npm@tnf-dev/api
    1.0.8
  • npm@tnf-dev/core
    1.0.8
  • npm@tnf-dev/js
    1.0.8
  • npm@tnf-dev/mui
    1.0.8
  • npm@tnf-dev/react
    1.0.8
  • npm@ui-ux-gang/devextreme-angular-rpk
    24.1.7
  • npm@yoobic/design-system
    6.5.17
  • npm@yoobic/jpeg-camera-es6
    1.0.13
  • npm@yoobic/yobi
    8.7.53
  • npmairchief
    0.3.1
  • npmairpilot
    0.8.8
  • npmangulartics2
    14.1.114.1.2
  • npmbrowser-webdriver-downloader
    3.0.8
  • npmcapacitor-notificationhandler
    0.0.20.0.3
  • npmcapacitor-plugin-healthapp
    0.0.20.0.3
  • npmcapacitor-plugin-ihealth
    1.1.81.1.9
  • npmcapacitor-plugin-vonage
    1.0.21.0.3
  • npmcapacitorandroidpermissions
    0.0.40.0.5
  • npmconfig-cordova
    0.8.5
  • npmcordova-plugin-voxeet2
    1.0.24
  • npmcordova-voxeet
    1.0.32
  • npmcreate-hest-app
    0.1.9
  • npmdb-evo
    1.1.41.1.5
  • npmdevextreme-angular-rpk
    21.2.8
  • npmdevextreme-rpk
    21.2.8
  • npmember-browser-services
    5.0.25.0.3
  • npmember-headless-form
    1.1.21.1.3
  • npmember-headless-form-yup
    1.0.1
  • npmember-headless-table
    2.1.52.1.6
  • npmember-url-hash-polyfill
    1.0.121.0.13
  • npmember-velcro
    2.2.12.2.2
  • npmencounter-playground
    0.0.20.0.30.0.40.0.5
  • npmeslint-config-crowdstrike
    11.0.211.0.3
  • npmeslint-config-crowdstrike-node
    4.0.34.0.4
  • npmeslint-config-teselagen
    6.1.76.1.8
  • npmglobalize-rpk
    1.7.4
  • npmgraphql-sequelize-teselagen
    5.3.85.3.9
  • npmhtml-to-base64-image
    1.0.2
  • npmjson-rules-engine-simplified
    0.2.10.2.30.2.4
  • npmjumpgate
    0.0.2
  • npmkoa2-swagger-ui
    5.11.15.11.2
  • npmmcfly-semantic-release
    1.3.1
  • npmmcp-knowledge-base
    0.0.2
  • npmmcp-knowledge-graph
    1.2.1
  • npmmobioffice-cli
    1.0.3
  • npmmonorepo-next
    13.0.113.0.2
  • npmmstate-angular
    0.4.4
  • npmmstate-cli
    0.4.7
  • npmmstate-dev-react
    1.1.1
  • npmmstate-react
    1.6.5
  • npmng2-file-upload
    7.0.27.0.38.0.18.0.28.0.39.0.1
  • npmngx-bootstrap
    18.1.419.0.319.0.420.0.320.0.420.0.520.0.6
  • npmngx-color
    10.0.110.0.2
  • npmngx-toastr
    19.0.119.0.2
  • npmngx-trend
    8.0.1
  • npmngx-ws
    1.1.51.1.6
  • npmoradm-to-gql
    35.0.1435.0.15
  • npmoradm-to-sqlz
    1.1.21.1.4
  • npmove-auto-annotate
    0.0.90.0.10
  • npmpm2-gelf-json
    1.0.41.0.5
  • npmprintjs-rpk
    1.6.1
  • npmreact-complaint-image
    0.0.320.0.340.0.35
  • npmreact-jsonschema-form-conditionals
    0.3.180.3.200.3.21
  • npmreact-jsonschema-form-extras
    1.0.31.0.4
  • npmreact-jsonschema-rxnt-extras
    0.4.80.4.9
  • npmremark-preset-lint-crowdstrike
    4.0.14.0.2
  • npmrxnt-authentication
    0.0.30.0.40.0.50.0.6
  • npmrxnt-healthchecks-nestjs
    1.0.21.0.31.0.41.0.5
  • npmrxnt-kue
    1.0.41.0.51.0.61.0.7
  • npmswc-plugin-component-annotate
    1.9.11.9.2
  • npmtbssnch
    1.0.2
  • npmteselagen-interval-tree
    1.1.2
  • npmtg-client-query-builder
    2.14.42.14.5
  • npmtg-redbird
    1.3.11.3.2
  • npmtg-seq-gen
    1.0.91.0.10
  • npmthangved-react-grid
    1.0.3
  • npmts-gaussian
    3.0.53.0.6
  • npmts-imports
    1.0.11.0.2
  • npmtvi-cli
    0.1.5
  • npmve-bamreader
    0.2.60.2.7
  • npmve-editor
    1.0.11.0.2
  • npmverror-extra
    6.0.1
  • npmvoip-callkit
    1.0.21.0.3
  • npmwdio-web-reporter
    0.1.3
  • npmyargs-help-output
    5.0.3
  • npmyoo-styles
    6.0.326

Impact

  • TruffleHog-driven secret discovery on dev/CI machines
  • Public exposure of private repositories ("-migration" rename pattern)
  • Stolen-credential propagation to any reachable npm package
  • Malicious GitHub Actions workflows for repository-secret exfil
  • High-blast-radius packages hit: @ctrl/tinycolor, ngx-bootstrap, ngx-toastr, @crowdstrike/*

What to do

  1. 1Rotate npm + GitHub tokens used in any environment that resolved affected versions
  2. 2Audit your GitHub org for public repos created under your account or with "Shai-Hulud" in the name
  3. 3Review private repos for unexpected "-migration" public twins
  4. 4Investigate any unexpected publish activity on packages you own
  5. 5For projects using @crowdstrike/* scopes, treat any host that built after 15 Sept 2025 as suspect until verified

References

npm-2025-09-shai-hulud-original