Original Shai-Hulud npm worm
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/*).
- 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-scrollbar20.0.20 - npm
@ahmedhfarag/ngx-virtual-scroller4.0.4 - npm
@art-ws/common2.0.28 - npm
@art-ws/config-eslint2.0.42.0.5 - npm
@art-ws/config-ts2.0.72.0.8 - npm
@art-ws/db-context2.0.24 - npm
@art-ws/di2.0.282.0.32 - npm
@art-ws/di-node2.0.13 - npm
@art-ws/eslint1.0.51.0.6 - npm
@art-ws/fastify-http-server2.0.242.0.27 - npm
@art-ws/http-server2.0.212.0.25 - npm
@art-ws/openapi0.1.90.1.12 - npm
@art-ws/package-base1.0.51.0.6 - npm
@art-ws/prettier1.0.51.0.6 - npm
@art-ws/slf2.0.152.0.22 - npm
@art-ws/ssl-info1.0.91.0.10 - npm
@art-ws/web-app1.0.31.0.4 - npm
@basic-ui-components-stc/basic-ui-components1.0.5 - npm
@crowdstrike/commitlint8.1.18.1.2 - npm
@crowdstrike/falcon-shoelace0.4.10.4.2 - npm
@crowdstrike/foundry-js0.19.10.19.2 - npm
@crowdstrike/glide-core0.34.20.34.3 - npm
@crowdstrike/logscale-dashboard1.205.11.205.2 - npm
@crowdstrike/logscale-file-editor1.205.11.205.2 - npm
@crowdstrike/logscale-parser-edit1.205.11.205.2 - npm
@crowdstrike/logscale-search1.205.11.205.2 - npm
@crowdstrike/tailwind-toucan-base5.0.15.0.2 - npm
@ctrl/deluge7.2.17.2.2 - npm
@ctrl/golang-template1.4.21.4.3 - npm
@ctrl/magnet-link4.0.34.0.4 - npm
@ctrl/ngx-codemirror7.0.17.0.2 - npm
@ctrl/ngx-csv6.0.16.0.2 - npm
@ctrl/ngx-emoji-mart9.2.19.2.2 - npm
@ctrl/ngx-rightclick4.0.14.0.2 - npm
@ctrl/qbittorrent9.7.19.7.2 - npm
@ctrl/react-adsense2.0.12.0.2 - npm
@ctrl/shared-torrent6.3.16.3.2 - npm
@ctrl/tinycolor4.1.14.1.2 - npm
@ctrl/torrent-file4.1.14.1.2 - npm
@ctrl/transmission7.3.1 - npm
@ctrl/ts-base324.0.14.0.2 - npm
@hestjs/core0.2.1 - npm
@hestjs/cqrs0.1.6 - npm
@hestjs/demo0.1.2 - npm
@hestjs/eslint-config0.1.2 - npm
@hestjs/logger0.1.6 - npm
@hestjs/scalar0.1.7 - npm
@hestjs/validation0.1.6 - npm
@nativescript-community/arraybuffers1.1.61.1.71.1.8 - npm
@nativescript-community/gesturehandler2.0.35 - npm
@nativescript-community/perms3.0.53.0.63.0.73.0.83.0.9 - npm
@nativescript-community/sentry4.6.43 - npm
@nativescript-community/sqlite3.5.23.5.33.5.43.5.5 - npm
@nativescript-community/text1.6.91.6.101.6.111.6.121.6.13 - npm
@nativescript-community/typeorm0.2.300.2.310.2.320.2.33 - npm
@nativescript-community/ui-collectionview6.0.6 - npm
@nativescript-community/ui-document-picker1.1.271.1.2813.0.32 - npm
@nativescript-community/ui-drawer0.1.30 - npm
@nativescript-community/ui-image4.5.6 - npm
@nativescript-community/ui-label1.3.351.3.361.3.37 - npm
@nativescript-community/ui-material-bottom-navigation7.2.727.2.737.2.747.2.75 - npm
@nativescript-community/ui-material-bottomsheet7.2.72 - npm
@nativescript-community/ui-material-core7.2.727.2.737.2.747.2.757.2.76 - npm
@nativescript-community/ui-material-core-tabs7.2.727.2.737.2.747.2.757.2.76 - npm
@nativescript-community/ui-material-ripple7.2.727.2.737.2.747.2.75 - npm
@nativescript-community/ui-material-tabs7.2.727.2.737.2.747.2.75 - npm
@nativescript-community/ui-pager14.1.3614.1.3714.1.38 - npm
@nativescript-community/ui-pulltorefresh2.5.42.5.52.5.62.5.7 - npm
@nexe/config-manager0.1.1 - npm
@nexe/eslint-config0.1.1 - npm
@nexe/logger0.1.3 - npm
@nstudio/angular20.0.420.0.520.0.6 - npm
@nstudio/focus20.0.420.0.520.0.6 - npm
@nstudio/nativescript-checkbox2.0.62.0.72.0.82.0.9 - npm
@nstudio/nativescript-loading-indicator5.0.15.0.25.0.35.0.4 - npm
@nstudio/ui-collectionview5.1.115.1.125.1.135.1.14 - npm
@nstudio/web20.0.4 - npm
@nstudio/web-angular20.0.4 - npm
@nstudio/xplat20.0.520.0.620.0.7 - npm
@nstudio/xplat-utils20.0.520.0.620.0.7 - npm
@operato/board9.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-grist9.0.299.0.359.0.369.0.37 - npm
@operato/graphql9.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/headroom9.0.29.0.359.0.369.0.37 - npm
@operato/help9.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/i18n9.0.359.0.369.0.37 - npm
@operato/input9.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/layout9.0.359.0.369.0.37 - npm
@operato/popup9.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-refresh9.0.369.0.379.0.389.0.399.0.409.0.419.0.42 - npm
@operato/shell9.0.229.0.359.0.369.0.379.0.389.0.39 - npm
@operato/styles9.0.29.0.359.0.369.0.37 - npm
@operato/utils9.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-parsers0.4.290.4.30 - npm
@teselagen/bounce-loader0.3.160.3.17 - npm
@teselagen/file-utils0.3.210.3.22 - npm
@teselagen/liquibase-tools0.4.1 - npm
@teselagen/ove0.7.390.7.40 - npm
@teselagen/range-utils0.3.140.3.15 - npm
@teselagen/react-list0.8.190.8.20 - npm
@teselagen/react-table6.10.196.10.206.10.216.10.22 - npm
@teselagen/sequence-utils0.3.330.3.34 - npm
@teselagen/ui0.9.90.9.10 - npm
@thangved/callback-window1.1.4 - npm
@things-factory/attachment-base9.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-base9.0.429.0.439.0.449.0.45 - npm
@things-factory/email-base9.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/env9.0.429.0.439.0.449.0.45 - npm
@things-factory/integration-base9.0.429.0.439.0.449.0.45 - npm
@things-factory/integration-marketplace9.0.429.0.439.0.449.0.45 - npm
@things-factory/shell9.0.429.0.439.0.449.0.45 - npm
@tnf-dev/api1.0.8 - npm
@tnf-dev/core1.0.8 - npm
@tnf-dev/js1.0.8 - npm
@tnf-dev/mui1.0.8 - npm
@tnf-dev/react1.0.8 - npm
@ui-ux-gang/devextreme-angular-rpk24.1.7 - npm
@yoobic/design-system6.5.17 - npm
@yoobic/jpeg-camera-es61.0.13 - npm
@yoobic/yobi8.7.53 - npm
airchief0.3.1 - npm
airpilot0.8.8 - npm
angulartics214.1.114.1.2 - npm
browser-webdriver-downloader3.0.8 - npm
capacitor-notificationhandler0.0.20.0.3 - npm
capacitor-plugin-healthapp0.0.20.0.3 - npm
capacitor-plugin-ihealth1.1.81.1.9 - npm
capacitor-plugin-vonage1.0.21.0.3 - npm
capacitorandroidpermissions0.0.40.0.5 - npm
config-cordova0.8.5 - npm
cordova-plugin-voxeet21.0.24 - npm
cordova-voxeet1.0.32 - npm
create-hest-app0.1.9 - npm
db-evo1.1.41.1.5 - npm
devextreme-angular-rpk21.2.8 - npm
devextreme-rpk21.2.8 - npm
ember-browser-services5.0.25.0.3 - npm
ember-headless-form1.1.21.1.3 - npm
ember-headless-form-yup1.0.1 - npm
ember-headless-table2.1.52.1.6 - npm
ember-url-hash-polyfill1.0.121.0.13 - npm
ember-velcro2.2.12.2.2 - npm
encounter-playground0.0.20.0.30.0.40.0.5 - npm
eslint-config-crowdstrike11.0.211.0.3 - npm
eslint-config-crowdstrike-node4.0.34.0.4 - npm
eslint-config-teselagen6.1.76.1.8 - npm
globalize-rpk1.7.4 - npm
graphql-sequelize-teselagen5.3.85.3.9 - npm
html-to-base64-image1.0.2 - npm
json-rules-engine-simplified0.2.10.2.30.2.4 - npm
jumpgate0.0.2 - npm
koa2-swagger-ui5.11.15.11.2 - npm
mcfly-semantic-release1.3.1 - npm
mcp-knowledge-base0.0.2 - npm
mcp-knowledge-graph1.2.1 - npm
mobioffice-cli1.0.3 - npm
monorepo-next13.0.113.0.2 - npm
mstate-angular0.4.4 - npm
mstate-cli0.4.7 - npm
mstate-dev-react1.1.1 - npm
mstate-react1.6.5 - npm
ng2-file-upload7.0.27.0.38.0.18.0.28.0.39.0.1 - npm
ngx-bootstrap18.1.419.0.319.0.420.0.320.0.420.0.520.0.6 - npm
ngx-color10.0.110.0.2 - npm
ngx-toastr19.0.119.0.2 - npm
ngx-trend8.0.1 - npm
ngx-ws1.1.51.1.6 - npm
oradm-to-gql35.0.1435.0.15 - npm
oradm-to-sqlz1.1.21.1.4 - npm
ove-auto-annotate0.0.90.0.10 - npm
pm2-gelf-json1.0.41.0.5 - npm
printjs-rpk1.6.1 - npm
react-complaint-image0.0.320.0.340.0.35 - npm
react-jsonschema-form-conditionals0.3.180.3.200.3.21 - npm
react-jsonschema-form-extras1.0.31.0.4 - npm
react-jsonschema-rxnt-extras0.4.80.4.9 - npm
remark-preset-lint-crowdstrike4.0.14.0.2 - npm
rxnt-authentication0.0.30.0.40.0.50.0.6 - npm
rxnt-healthchecks-nestjs1.0.21.0.31.0.41.0.5 - npm
rxnt-kue1.0.41.0.51.0.61.0.7 - npm
swc-plugin-component-annotate1.9.11.9.2 - npm
tbssnch1.0.2 - npm
teselagen-interval-tree1.1.2 - npm
tg-client-query-builder2.14.42.14.5 - npm
tg-redbird1.3.11.3.2 - npm
tg-seq-gen1.0.91.0.10 - npm
thangved-react-grid1.0.3 - npm
ts-gaussian3.0.53.0.6 - npm
ts-imports1.0.11.0.2 - npm
tvi-cli0.1.5 - npm
ve-bamreader0.2.60.2.7 - npm
ve-editor1.0.11.0.2 - npm
verror-extra6.0.1 - npm
voip-callkit1.0.21.0.3 - npm
wdio-web-reporter0.1.3 - npm
yargs-help-output5.0.3 - npm
yoo-styles6.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
- 1Rotate npm + GitHub tokens used in any environment that resolved affected versions
- 2Audit your GitHub org for public repos created under your account or with "Shai-Hulud" in the name
- 3Review private repos for unexpected "-migration" public twins
- 4Investigate any unexpected publish activity on packages you own
- 5For projects using @crowdstrike/* scopes, treat any host that built after 15 Sept 2025 as suspect until verified