{
	"id": "bf3b9134-7ba1-4a18-bd0b-bd818e89d152",
	"created_at": "2026-04-06T00:15:55.236416Z",
	"updated_at": "2026-04-10T03:21:36.002145Z",
	"deleted_at": null,
	"sha1_hash": "1f51bd369182ebb87c17bfdb780510d2361eddfe",
	"title": "Shai-Hulud: Ongoing Package Supply Chain Worm Delivering Data-Stealing Malware",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 106503,
	"plain_text": "Shai-Hulud: Ongoing Package Supply Chain Worm Delivering\r\nData-Stealing Malware\r\nBy Merav Bar, Rami McCarthy, Barak Sharoni\r\nPublished: 2025-09-16 · Archived: 2026-04-05 15:18:34 UTC\r\nOn September 15, 2025, malicious versions of multiple popular packages were published to npm. They contained\r\na post-install script that harvested sensitive data and exfiltrated it to attacker-created public GitHub repos named\r\nShai-Hulud. Beyond data theft, the malware exhibits worm-like behaviour: when a compromised package\r\nencounters additional npm tokens in its environment, it will automatically publish malicious versions of any\r\npackages it can access - spreading across the npm ecosystem. Wiz Research assesses this campaign is directly\r\ndownstream of the late-August 2025 s1ngularity/Nx compromise (initial GitHub token theft to npm token theft to\r\nmass package poisoning). As the first successful self-propagating attack in the npm ecosystem, this appears to be\r\none of the most severe JavaScript supply-chain attacks observed to date.\r\nSeptember 17, 2025 10AM UTC: payload analysis section was added.\r\nSeptember 17, 2025 1PM UTC: additional packages and versions have been added to the appendix.\r\nOnce a version of one of the malicious packages is installed, the included payload uses the TruffleHog secret\r\nscanning tool to identify secrets, in addition to harvesting environment variables and IMDS-exposed cloud keys\r\nwhen available. \r\nAdditionally, the script validates collected credentials and, if it finds GitHub tokens, it abuses them in multiple\r\nways: \r\nThis attack is a self-propagating worm. When a compromised package encounters additional npm tokens in a\r\nvictim environment, it will automatically publish malicious versions of any packages it can access. See further\r\ndiscussion of the malicious code in Socket's initial analysis.\r\nBased on victimology, Wiz Research assesses this activity is tied to the recent s1ngularity / Nx supply chain\r\nattack, where initial GitHub token theft enabled the broader chain of compromise and leaking of formerly private\r\nrepositories. The initial npm packages that started this chain reaction included multiple known-compromised\r\nvictims of the s1ngularity attack.\r\nThe worm deploys a \"workflow script\" to /tmp/processor.sh , executing it to trigger automated branch\r\ncreation, triggering GitHub workflows to exfiltrate its secrets. Similarly, it drops a \"migration script\" at\r\n/tmp/migrate-repos.sh , which, once executed, forces private repositories to be cloned and republished as public\r\nrepositories with the -migration suffix.\r\nDuring this process, the malware appears to use /tmp/github-migration as a temporary working directory for\r\ncloning and related operations - though this is not fully confirmed due to some obfuscation and irregularities in the\r\ncode. Importantly, the migration routine first creates the repository as private and then immediately flips its\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 1 of 10\n\nvisibility to public. This results in two observable GitHub events in quick succession: a CreateEvent followed\r\nby a PublicEvent .\r\nAnother observation, one of the payloads appears to be AI-generated, another variant lacks that same stylistic\r\npattern, suggesting it may have been copied from an external source that we have not yet identified.\r\nThe attacker exfiltrated data using webhook[.]site within a malicious GitHub Action. However, under the free\r\nplan used, the webhook can only receive a total of 100 callbacks. We observed that the webhook had been\r\ndeactivated by the platform for excessive activity. This renders the webhook based exfiltration non-functional.\r\nHowever, secrets will still be exposed in the workflow log on GitHub. \r\nWiz Research initially observed 36 GitHub users with secrets exposed in the “Shai-Hulud” repo ( data.json ,\r\ndouble–base64 encoded) and 8 users whose private repositories were force-migrated to public with the label\r\n“Shai-Hulud Migration.”\r\nTracking down repositories with the malicious workflow proved challenging, since GitHub doesn't index deleted\r\nbranches, commits, or file contents. Still, we were able to uncover 64 additional repositories where a shai-hulud\r\nbranch had been created, and in most of them, we found a commit containing the malicious workflow. In many\r\ncases, the workflow logs exposed sensitive secrets like GitHub tokens, NPM credentials, Atlassian keys, and\r\nDatadog API keys. These are still accessible as of writing this blog.\r\nDespite the clear propagation of the worm to additional npm packages, we have not currently observed the\r\ncreation of further repositories.\r\nRevoke and regenerate all GitHub tokens, npm tokens, SSH keys, API keys, and environment variable secrets that\r\nmay have been leaked in these repositories.\r\nMika AI, Wiz's AI assistant, can investigate new threat center items, analyze your environment for impact, and\r\ncreate recommendation plan to minimize impact, turning hours of manual analysis into minutes of AI-powered\r\ninsights.\r\nSimply ask Mika AI, \"How do I know if I'm affected by the latest Shai-Hulud NPM Supply Chain Attack?\", and get\r\ncomprehensive analysis, based on all Wiz capabilities of affected resources, exposure level, real-time threats and\r\nrisk, and receive step-by-step remediation recommendations.\r\n@ctrl/deluge (7.2.2, 7.2.1)\r\n@ctrl/golang-template (1.4.3, 1.4.2)\r\n@ctrl/magnet-link (4.0.4, 4.0.3)\r\n@ctrl/ngx-codemirror (7.0.2, 7.0.1)\r\n@ctrl/ngx-csv (6.0.2, 6.0.1)\r\n@ctrl/ngx-emoji-mart (9.2.2, 9.2.1)\r\n@ctrl/ngx-rightclick (4.0.2, 4.0.1)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 2 of 10\n\n@ctrl/qbittorrent (9.7.2, 9.7.1)\r\n@ctrl/react-adsense (2.0.2, 2.0.1)\r\n@ctrl/shared-torrent (6.3.2, 6.3.1)\r\n@ctrl/tinycolor@4.1.1, (4.1.2)\r\n@ctrl/torrent-file (4.1.2, 4.1.1)\r\n@ctrl/transmission (7.3.1)\r\n@ctrl/ts-base32 (4.0.2, 4.0.1)\r\n@nativescript-community/gesturehandler (2.0.35)\r\n@nativescript-community/sentry (4.6.43)\r\n@nativescript-community/text (1.6.13, 1.6.10, 1.6.11, 1.6.12, 1.6.9)\r\n@nativescript-community/ui-collectionview (6.0.6)\r\n@nativescript-community/ui-drawer (0.1.30)\r\n@nativescript-community/ui-image (4.5.6)\r\n@nativescript-community/ui-material-bottomsheet (7.2.72)\r\n@nativescript-community/ui-material-core (7.2.76, 7.2.72, 7.2.73, 7.2.74, 7.2.75)\r\n@nativescript-community/ui-material-core-tabs (7.2.76, 7.2.72, 7.2.73, 7.2.74, 7.2.75)\r\n@teselagen/bio-parsers (0.4.29, 0.4.30)\r\n@teselagen/bounce-loader (0.3.16, 0.3.17)\r\n@teselagen/file-utils (0.3.21, 0.3.22)\r\n@teselagen/liquibase-tools (0.4.1)\r\n@teselagen/ove (0.7.39, 0.7.40)\r\n@teselagen/range-utils (0.3.14, 0.3.15)\r\n@teselagen/react-list (0.8.19, 0.8.20)\r\n@teselagen/react-table (6.10.21, 6.10.19, 6.10.20, 6.10.22)\r\n@teselagen/sequence-utils (0.3.33, 0.3.34)\r\n@teselagen/ui (0.9.9, 0.9.10)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 3 of 10\n\nangulartics2 (14.1.2, 14.1.1)\r\nencounter-playground (0.0.4, 0.0.5, 0.0.2, 0.0.3)\r\neslint-config-teselagen (6.1.7, 6.1.8)\r\ngraphql-sequelize-teselagen (5.3.8, 5.3.9)\r\njson-rules-engine-simplified (0.2.3, 0.2.4, 0.2.1)\r\nkoa2-swagger-ui (5.11.2, 5.11.1)\r\nng2-file-upload (8.0.3, 7.0.2, 7.0.3, 8.0.1, 8.0.2, 9.0.1)\r\nngx-bootstrap (18.1.4, 19.0.3, 20.0.4, 20.0.5, 20.0.6, 19.0.4, 20.0.3)\r\nngx-color (10.0.2, 10.0.1)\r\nngx-toastr (19.0.2, 19.0.1)\r\nngx-trend (8.0.1)\r\noradm-to-gql (35.0.14, 35.0.15)\r\noradm-to-sqlz (1.1.4, 1.1.2)\r\nove-auto-annotate (0.0.9, 0.0.10)\r\nreact-complaint-image (0.0.34, 0.0.35, 0.0.32)\r\nreact-jsonschema-form-conditionals (0.3.20, 0.3.21, 0.3.18)\r\nreact-jsonschema-form-extras (1.0.3, 1.0.4)\r\nreact-jsonschema-rxnt-extras (0.4.8, 0.4.9)\r\nrxnt-authentication (0.0.5, 0.0.6, 0.0.3, 0.0.4)\r\nrxnt-healthchecks-nestjs (1.0.4, 1.0.5, 1.0.2, 1.0.3)\r\nrxnt-kue (1.0.6, 1.0.7, 1.0.4, 1.0.5)\r\nswc-plugin-component-annotate (1.9.2, 1.9.1)\r\ntg-client-query-builder (2.14.4, 2.14.5)\r\ntg-redbird (1.3.1, 1.3.2)\r\ntg-seq-gen (1.0.9, 1.0.10)\r\nts-gaussian (3.0.6, 3.0.5)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 4 of 10\n\nve-bamreader (0.2.6, 0.2.7)\r\nve-editor (1.0.1, 1.0.2)\r\n@ahmedhfarag/ngx-perfect-scrollbar (20.0.20)\r\n@ahmedhfarag/ngx-virtual-scroller (4.0.4)\r\n@art-ws/common (2.0.28)\r\n@art-ws/config-eslint (2.0.4, 2.0.5)\r\n@art-ws/config-ts (2.0.7, 2.0.8)\r\n@art-ws/db-context (2.0.24)\r\n@art-ws/di-node (2.0.13)\r\n@art-ws/di (2.0.28, 2.0.32)\r\n@art-ws/eslint (1.0.5, 1.0.6)\r\n@art-ws/fastify-http-server (2.0.24, 2.0.27)\r\n@art-ws/http-server (2.0.21, 2.0.25)\r\n@art-ws/openapi (0.1.12, 0.1.9)\r\n@art-ws/package-base (1.0.5, 1.0.6)\r\n@art-ws/prettier (1.0.5, 1.0.6)\r\n@art-ws/slf (2.0.15, 2.0.22)\r\n@art-ws/ssl-info (1.0.10, 1.0.9)\r\n@art-ws/web-app (1.0.3, 1.0.4)\r\n@crowdstrike/commitlint (8.1.1, 8.1.2)\r\n@crowdstrike/falcon-shoelace (0.4.1, 0.4.2)\r\n@crowdstrike/foundry-js (0.19.1, 0.19.2)\r\n@crowdstrike/glide-core (0.34.2, 0.34.3)\r\n@crowdstrike/logscale-dashboard (1.205.1, 1.205.2)\r\n@crowdstrike/logscale-file-editor (1.205.1, 1.205.2)\r\n@crowdstrike/logscale-parser-edit (1.205.1, 1.205.2)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 5 of 10\n\n@crowdstrike/logscale-search (1.205.1, 1.205.2)\r\n@crowdstrike/tailwind-toucan-base (5.0.1, 5.0.2)\r\n@ctrl/tinycolor (4.1.1, 4.1.2)\r\n@hestjs/core (0.2.1)\r\n@hestjs/cqrs (0.1.6)\r\n@hestjs/demo (0.1.2)\r\n@hestjs/eslint-config (0.1.2)\r\n@hestjs/logger (0.1.6)\r\n@hestjs/scalar (0.1.7)\r\n@hestjs/validation (0.1.6)\r\n@nativescript-community/arraybuffers (1.1.6, 1.1.7, 1.1.8)\r\n@nativescript-community/perms (3.0.5, 3.0.6, 3.0.7, 3.0.8, 3.0.9)\r\n@nativescript-community/sqlite (3.5.2, 3.5.3, 3.5.4, 3.5.5)\r\n@nativescript-community/typeorm (0.2.30, 0.2.31, 0.2.32, 0.2.33)\r\n@nativescript-community/ui-document-picker (1.1.27, 1.1.28, 13.0.32)\r\n@nativescript-community/ui-label (1.3.35, 1.3.36, 1.3.37)\r\n@nativescript-community/ui-material-bottom-navigation (7.2.72, 7.2.73, 7.2.74, 7.2.75)\r\n@nativescript-community/ui-material-ripple (7.2.72, 7.2.73, 7.2.74, 7.2.75)\r\n@nativescript-community/ui-material-tabs (7.2.72, 7.2.73, 7.2.74, 7.2.75)\r\n@nativescript-community/ui-pager (14.1.36, 14.1.37, 14.1.38)\r\n@nativescript-community/ui-pulltorefresh (2.5.4, 2.5.5, 2.5.6, 2.5.7)\r\n@nexe/config-manager (0.1.1)\r\n@nexe/eslint-config (0.1.1)\r\n@nexe/logger (0.1.3)\r\n@nstudio/angular (20.0.4, 20.0.5, 20.0.6)\r\n@nstudio/focus (20.0.4, 20.0.5, 20.0.6)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 6 of 10\n\n@nstudio/nativescript-checkbox (2.0.6, 2.0.7, 2.0.8, 2.0.9)\r\n@nstudio/nativescript-loading-indicator (5.0.1, 5.0.2, 5.0.3, 5.0.4)\r\n@nstudio/ui-collectionview (5.1.11, 5.1.12, 5.1.13, 5.1.14)\r\n@nstudio/web-angular (20.0.4)\r\n@nstudio/web (20.0.4)\r\n@nstudio/xplat-utils (20.0.5, 20.0.6, 20.0.7)\r\n@nstudio/xplat (20.0.5, 20.0.6, 20.0.7)\r\n@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)\r\n@operato/data-grist (9.0.29, 9.0.35, 9.0.36, 9.0.37)\r\n@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,\r\n9.0.46)\r\n@operato/headroom (9.0.2, 9.0.35, 9.0.36, 9.0.37)\r\n@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)\r\n@operato/i18n (9.0.35, 9.0.36, 9.0.37)\r\n@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,\r\n9.0.47, 9.0.48)\r\n@operato/layout (9.0.35, 9.0.36, 9.0.37)\r\n@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,\r\n9.0.46, 9.0.49)\r\n@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)\r\n@operato/shell (9.0.22, 9.0.35, 9.0.36, 9.0.37, 9.0.38, 9.0.39)\r\n@operato/styles (9.0.2, 9.0.35, 9.0.36, 9.0.37)\r\n@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,\r\n9.0.49)\r\n@thangved/callback-window (1.1.4)\r\n@things-factory/attachment-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,\r\n9.0.52, 9.0.53, 9.0.54, 9.0.55)\r\n@things-factory/auth-base (9.0.42, 9.0.43, 9.0.44, 9.0.45)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 7 of 10\n\n@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,\r\n9.0.53, 9.0.54, 9.0.55, 9.0.56, 9.0.57, 9.0.58, 9.0.59)\r\n@things-factory/env (9.0.42, 9.0.43, 9.0.44, 9.0.45)\r\n@things-factory/integration-base (9.0.42, 9.0.43, 9.0.44, 9.0.45)\r\n@things-factory/integration-marketplace (9.0.42, 9.0.43, 9.0.44, 9.0.45)\r\n@things-factory/shell (9.0.42, 9.0.43, 9.0.44, 9.0.45)\r\n@tnf-dev/api (1.0.8)\r\n@tnf-dev/core (1.0.8)\r\n@tnf-dev/js (1.0.8)\r\n@tnf-dev/mui (1.0.8)\r\n@tnf-dev/react (1.0.8)\r\n@ui-ux-gang/devextreme-angular-rpk (24.1.7)\r\n@yoobic/design-system (6.5.17)\r\n@yoobic/jpeg-camera-es6 (1.0.13)\r\n@yoobic/yobi (8.7.53)\r\nairchief (0.3.1)\r\nairpilot (0.8.8)\r\nbrowser-webdriver-downloader (3.0.8)\r\ncapacitor-notificationhandler (0.0.2, 0.0.3)\r\ncapacitor-plugin-healthapp (0.0.2, 0.0.3)\r\ncapacitor-plugin-ihealth (1.1.8, 1.1.9)\r\ncapacitor-plugin-vonage (1.0.2, 1.0.3)\r\ncapacitorandroidpermissions (0.0.4, 0.0.5)\r\nconfig-cordova (0.8.5)\r\ncordova-plugin-voxeet2 (1.0.24)\r\ncordova-voxeet (1.0.32)\r\ncreate-hest-app (0.1.9)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 8 of 10\n\ndb-evo (1.1.4, 1.1.5)\r\ndevextreme-angular-rpk (21.2.8)\r\nember-browser-services (5.0.2, 5.0.3)\r\nember-headless-form-yup (1.0.1)\r\nember-headless-form (1.1.2, 1.1.3)\r\nember-headless-table (2.1.5, 2.1.6)\r\nember-url-hash-polyfill (1.0.12, 1.0.13)\r\nember-velcro (2.2.1, 2.2.2)\r\neslint-config-crowdstrike-node (4.0.3, 4.0.4)\r\neslint-config-crowdstrike (11.0.2, 11.0.3)\r\nglobalize-rpk (1.7.4)\r\nhtml-to-base64-image (1.0.2)\r\njumpgate (0.0.2)\r\nmcfly-semantic-release (1.3.1)\r\nmcp-knowledge-base (0.0.2)\r\nmcp-knowledge-graph (1.2.1)\r\nmobioffice-cli (1.0.3)\r\nmonorepo-next (13.0.1, 13.0.2)\r\nmstate-angular (0.4.4)\r\nmstate-cli (0.4.7)\r\nmstate-dev-react (1.1.1)\r\nmstate-react (1.6.5)\r\nngx-ws (1.1.5, 1.1.6)\r\npm2-gelf-json (1.0.4, 1.0.5)\r\nprintjs-rpk (1.6.1)\r\nremark-preset-lint-crowdstrike (4.0.1, 4.0.2)\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 9 of 10\n\ntbssnch (1.0.2)\r\nteselagen-interval-tree (1.1.2)\r\nthangved-react-grid (1.0.3)\r\nts-imports (1.0.1, 1.0.2)\r\ntvi-cli (0.1.5)\r\nverror-extra (6.0.1)\r\nvoip-callkit (1.0.2, 1.0.3)\r\nwdio-web-reporter (0.1.3)\r\nyargs-help-output (5.0.3)\r\nyoo-styles (6.0.326)\r\ndevextreme-rpk (21.2.8)\r\n@basic-ui-components-stc/basic-ui-components (1.0.5)\r\nSource: https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nhttps://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack"
	],
	"report_names": [
		"shai-hulud-npm-supply-chain-attack"
	],
	"threat_actors": [],
	"ts_created_at": 1775434555,
	"ts_updated_at": 1775791296,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/1f51bd369182ebb87c17bfdb780510d2361eddfe.pdf",
		"text": "https://archive.orkl.eu/1f51bd369182ebb87c17bfdb780510d2361eddfe.txt",
		"img": "https://archive.orkl.eu/1f51bd369182ebb87c17bfdb780510d2361eddfe.jpg"
	}
}