hulud-party-scanner 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ Project integrity scanner for known vulnerabilities and suspicious patterns related to the Shai-Hulud supply-chain attack.
2
+
3
+ This project is a Node.js implementation based on the original shell script from [sng-jroji/hulud-party](https://github.com/sng-jroji/hulud-party).
@@ -0,0 +1,588 @@
1
+ # This file contains 517 confirmed compromised package versions from the complete JFrog analysis
2
+ # The Shai-Hulud attack was self-replicating, so new compromised packages may still be discovered
3
+ #
4
+ # Sources: StepSecurity, Wiz.io, Semgrep, JFrog security advisories
5
+ # Format: package_name:version
6
+ #
7
+ # MAINTAINING THIS LIST:
8
+ # - Add new compromised packages as they are discovered
9
+ # - Check security advisories regularly for updates:
10
+ # * https://www.stepsecurity.io/blog/ctrl-tinycolor-and-40-npm-packages-compromised
11
+ # * https://semgrep.dev/blog/2025/security-advisory-npm-packages-using-secret-scanning-tools-to-steal-credentials/
12
+ # * https://jfrog.com/blog/shai-hulud-npm-supply-chain-attack-new-compromised-packages-detected/
13
+ # * https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack
14
+ # * https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages
15
+ # - Format: one package:version per line
16
+ # - Lines starting with # are comments and will be ignored
17
+ #
18
+ # DO NOT REMOVE EXISTING PACKAGES - only add new ones as they are discovered
19
+
20
+ # @ctrl namespace - primary targets
21
+ @ctrl/tinycolor:4.1.0
22
+ @ctrl/tinycolor:4.1.1
23
+ @ctrl/tinycolor:4.1.2
24
+ @ctrl/deluge:1.2.0
25
+ @ctrl/deluge:7.2.1
26
+ @ctrl/deluge:7.2.2
27
+ @ctrl/golang-template:1.4.2
28
+ @ctrl/golang-template:1.4.3
29
+ @ctrl/magnet-link:4.0.3
30
+ @ctrl/magnet-link:4.0.4
31
+
32
+ # @ahmedhfarag namespace
33
+ @ahmedhfarag/ngx-perfect-scrollbar:20.0.20
34
+ @ahmedhfarag/ngx-virtual-scroller:4.0.4
35
+
36
+ # @art-ws namespace - 16+ packages
37
+ @art-ws/common:2.0.22
38
+ @art-ws/common:2.0.28
39
+ @art-ws/config-eslint:2.0.4
40
+ @art-ws/config-eslint:2.0.5
41
+ @art-ws/config-ts:2.0.7
42
+ @art-ws/config-ts:2.0.8
43
+ @art-ws/db-context:2.0.24
44
+ @art-ws/di:2.0.28
45
+ @art-ws/di:2.0.32
46
+ @art-ws/di-node:2.0.13
47
+ @art-ws/eslint:1.0.5
48
+ @art-ws/eslint:1.0.6
49
+ @art-ws/fastify-http-server:2.0.24
50
+ @art-ws/fastify-http-server:2.0.27
51
+ @art-ws/http-server:2.0.21
52
+ @art-ws/http-server:2.0.25
53
+ @art-ws/openapi:0.1.9
54
+ @art-ws/openapi:0.1.12
55
+ @art-ws/package-base:1.0.5
56
+ @art-ws/package-base:1.0.6
57
+ @art-ws/prettier:1.0.5
58
+ @art-ws/prettier:1.0.6
59
+ @art-ws/slf:2.0.15
60
+ @art-ws/slf:2.0.22
61
+ @art-ws/ssl-info:1.0.9
62
+ @art-ws/ssl-info:1.0.10
63
+ @art-ws/web-app:1.0.3
64
+ @art-ws/web-app:1.0.4
65
+
66
+ # @crowdstrike namespace - 25+ packages
67
+ @crowdstrike/commitlint:8.1.1
68
+ @crowdstrike/commitlint:8.1.2
69
+ @crowdstrike/falcon-shoelace:0.4.1
70
+ @crowdstrike/falcon-shoelace:0.4.2
71
+ @crowdstrike/foundry-js:0.19.1
72
+ @crowdstrike/foundry-js:0.19.2
73
+ @crowdstrike/glide-core:0.34.2
74
+ @crowdstrike/glide-core:0.34.3
75
+ @crowdstrike/logscale-dashboard:1.205.1
76
+ @crowdstrike/logscale-dashboard:1.205.2
77
+ @crowdstrike/logscale-file-editor:1.205.1
78
+ @crowdstrike/logscale-file-editor:1.205.2
79
+ @crowdstrike/logscale-parser-edit:1.205.1
80
+ @crowdstrike/logscale-parser-edit:1.205.2
81
+ @crowdstrike/logscale-search:1.205.1
82
+ @crowdstrike/logscale-search:1.205.2
83
+ @crowdstrike/tailwind-toucan-base:5.0.1
84
+ @crowdstrike/tailwind-toucan-base:5.0.2
85
+
86
+ # @hestjs namespace
87
+ @hestjs/core:1.0.1
88
+ @hestjs/core:1.0.2
89
+
90
+ # @nstudio namespace - multiple packages with various versions
91
+ @nstudio/angular:20.0.4
92
+ @nstudio/angular:20.0.5
93
+ @nstudio/angular:20.0.6
94
+ @nstudio/focus:20.0.4
95
+ @nstudio/focus:20.0.5
96
+ @nstudio/focus:20.0.6
97
+ @nstudio/nativescript-checkbox:2.0.6
98
+ @nstudio/nativescript-checkbox:2.0.7
99
+ @nstudio/nativescript-checkbox:2.0.8
100
+ @nstudio/nativescript-checkbox:2.0.9
101
+ @nstudio/nativescript-loading-indicator:5.0.1
102
+ @nstudio/nativescript-loading-indicator:5.0.2
103
+ @nstudio/nativescript-loading-indicator:5.0.3
104
+ @nstudio/nativescript-loading-indicator:5.0.4
105
+ @nstudio/ui-collectionview:5.1.11
106
+ @nstudio/ui-collectionview:5.1.12
107
+ @nstudio/ui-collectionview:5.1.13
108
+ @nstudio/ui-collectionview:5.1.14
109
+ @nstudio/web-angular:20.0.4
110
+ @nstudio/web:20.0.4
111
+ @nstudio/xplat-utils:20.0.5
112
+ @nstudio/xplat-utils:20.0.6
113
+
114
+ # @operato namespace - multiple packages with 9.0.x versions
115
+ @operato/board:9.0.36
116
+ @operato/board:9.0.37
117
+ @operato/board:9.0.38
118
+ @operato/board:9.0.39
119
+ @operato/board:9.0.40
120
+ @operato/board:9.0.41
121
+ @operato/board:9.0.42
122
+ @operato/board:9.0.43
123
+ @operato/board:9.0.44
124
+ @operato/board:9.0.45
125
+ @operato/board:9.0.46
126
+ @operato/data-grist:9.0.29
127
+ @operato/data-grist:9.0.35
128
+ @operato/data-grist:9.0.36
129
+ @operato/data-grist:9.0.37
130
+ @operato/graphql:9.0.22
131
+ @operato/graphql:9.0.35
132
+ @operato/graphql:9.0.36
133
+ @operato/graphql:9.0.37
134
+ @operato/graphql:9.0.38
135
+ @operato/graphql:9.0.39
136
+ @operato/graphql:9.0.40
137
+ @operato/graphql:9.0.41
138
+ @operato/graphql:9.0.42
139
+ @operato/graphql:9.0.43
140
+ @operato/graphql:9.0.44
141
+ @operato/graphql:9.0.45
142
+ @operato/graphql:9.0.46
143
+ @operato/headroom:9.0.2
144
+ @operato/headroom:9.0.35
145
+ @operato/headroom:9.0.36
146
+ @operato/headroom:9.0.37
147
+ @operato/help:9.0.35
148
+ @operato/help:9.0.36
149
+ @operato/help:9.0.37
150
+ @operato/help:9.0.38
151
+ @operato/help:9.0.39
152
+ @operato/help:9.0.40
153
+ @operato/help:9.0.41
154
+ @operato/help:9.0.42
155
+ @operato/help:9.0.43
156
+ @operato/help:9.0.44
157
+ @operato/help:9.0.45
158
+ @operato/help:9.0.46
159
+ @operato/i18n:9.0.35
160
+ @operato/i18n:9.0.36
161
+ @operato/i18n:9.0.37
162
+ @operato/input:9.0.27
163
+ @operato/input:9.0.35
164
+ @operato/input:9.0.36
165
+ @operato/input:9.0.37
166
+ @operato/input:9.0.38
167
+ @operato/input:9.0.39
168
+ @operato/input:9.0.40
169
+ @operato/input:9.0.41
170
+ @operato/input:9.0.42
171
+ @operato/input:9.0.43
172
+ @operato/input:9.0.44
173
+ @operato/input:9.0.45
174
+ @operato/input:9.0.46
175
+ @operato/layout:9.0.35
176
+ @operato/layout:9.0.36
177
+ @operato/layout:9.0.37
178
+ @operato/popup:9.0.22
179
+ @operato/popup:9.0.35
180
+ @operato/popup:9.0.36
181
+ @operato/popup:9.0.37
182
+ @operato/popup:9.0.38
183
+ @operato/popup:9.0.39
184
+ @operato/popup:9.0.40
185
+ @operato/popup:9.0.41
186
+ @operato/popup:9.0.42
187
+ @operato/popup:9.0.43
188
+ @operato/popup:9.0.44
189
+ @operato/popup:9.0.45
190
+ @operato/popup:9.0.46
191
+ @operato/pull-to-refresh:9.0.36
192
+ @operato/pull-to-refresh:9.0.37
193
+ @operato/pull-to-refresh:9.0.38
194
+ @operato/pull-to-refresh:9.0.39
195
+ @operato/pull-to-refresh:9.0.40
196
+ @operato/pull-to-refresh:9.0.41
197
+ @operato/pull-to-refresh:9.0.42
198
+ @operato/shell:9.0.22
199
+ @operato/shell:9.0.35
200
+ @operato/shell:9.0.36
201
+ @operato/shell:9.0.37
202
+ @operato/shell:9.0.38
203
+ @operato/shell:9.0.39
204
+ @operato/styles:9.0.2
205
+ @operato/styles:9.0.35
206
+ @operato/styles:9.0.36
207
+ @operato/styles:9.0.37
208
+ @operato/utils:9.0.22
209
+ @operato/utils:9.0.35
210
+ @operato/utils:9.0.36
211
+ @operato/utils:9.0.37
212
+ @operato/utils:9.0.38
213
+ @operato/utils:9.0.39
214
+ @operato/utils:9.0.40
215
+ @operato/utils:9.0.41
216
+ @operato/utils:9.0.42
217
+ @operato/utils:9.0.43
218
+ @operato/utils:9.0.44
219
+ @operato/utils:9.0.45
220
+ @operato/utils:9.0.46
221
+
222
+ # @teselagen namespace - multiple packages with 0.x versions
223
+ @teselagen/bio-parsers:0.4.29
224
+ @teselagen/bio-parsers:0.4.30
225
+ @teselagen/bounce-loader:0.3.16
226
+ @teselagen/bounce-loader:0.3.17
227
+ @teselagen/file-utils:0.3.21
228
+ @teselagen/file-utils:0.3.22
229
+ @teselagen/liquibase-tools:0.4.1
230
+ @teselagen/ove:0.7.39
231
+ @teselagen/ove:0.7.40
232
+ @teselagen/range-utils:0.3.14
233
+ @teselagen/range-utils:0.3.15
234
+ @teselagen/react-list:0.8.19
235
+ @teselagen/react-list:0.8.20
236
+ @teselagen/react-table:6.10.19
237
+ @teselagen/react-table:6.10.20
238
+ @teselagen/react-table:6.10.21
239
+ @teselagen/react-table:6.10.22
240
+ @teselagen/sequence-utils:0.3.33
241
+ @teselagen/sequence-utils:0.3.34
242
+ @teselagen/ui:0.9.9
243
+ @teselagen/ui:0.9.10
244
+
245
+ # @things-factory namespace - multiple packages with 9.0.x versions
246
+ @things-factory/attachment-base:9.0.43
247
+ @things-factory/attachment-base:9.0.44
248
+ @things-factory/attachment-base:9.0.45
249
+ @things-factory/attachment-base:9.0.46
250
+ @things-factory/attachment-base:9.0.47
251
+ @things-factory/attachment-base:9.0.48
252
+ @things-factory/attachment-base:9.0.49
253
+ @things-factory/attachment-base:9.0.50
254
+ @things-factory/auth-base:9.0.43
255
+ @things-factory/auth-base:9.0.44
256
+ @things-factory/auth-base:9.0.45
257
+ @things-factory/email-base:9.0.42
258
+ @things-factory/email-base:9.0.43
259
+ @things-factory/email-base:9.0.44
260
+ @things-factory/email-base:9.0.45
261
+ @things-factory/email-base:9.0.46
262
+ @things-factory/email-base:9.0.47
263
+ @things-factory/email-base:9.0.48
264
+ @things-factory/email-base:9.0.49
265
+ @things-factory/email-base:9.0.50
266
+ @things-factory/email-base:9.0.51
267
+ @things-factory/email-base:9.0.52
268
+ @things-factory/email-base:9.0.53
269
+ @things-factory/email-base:9.0.54
270
+ @things-factory/env:9.0.42
271
+ @things-factory/env:9.0.43
272
+ @things-factory/env:9.0.44
273
+ @things-factory/env:9.0.45
274
+ @things-factory/integration-base:9.0.43
275
+ @things-factory/integration-base:9.0.44
276
+ @things-factory/integration-base:9.0.45
277
+ @things-factory/integration-marketplace:9.0.43
278
+ @things-factory/integration-marketplace:9.0.44
279
+ @things-factory/integration-marketplace:9.0.45
280
+
281
+ # @nativescript-community namespace - 40+ packages
282
+ @nativescript-community/push:1.0.0
283
+ @nativescript-community/sqlite:3.5.2
284
+ @nativescript-community/sqlite:3.5.3
285
+ @nativescript-community/sqlite:3.5.4
286
+ @nativescript-community/sqlite:3.5.5
287
+ @nativescript-community/ui-material-activityindicator:7.2.49
288
+ @nativescript-community/ui-material-bottomnavigationbar:7.2.49
289
+ @nativescript-community/ui-material-bottomsheet:7.2.49
290
+ @nativescript-community/ui-material-button:7.2.49
291
+ @nativescript-community/ui-material-cardview:7.2.49
292
+ @nativescript-community/ui-material-core:7.2.49
293
+ @nativescript-community/ui-material-dialogs:7.2.49
294
+ @nativescript-community/ui-material-floatingactionbutton:7.2.49
295
+ @nativescript-community/ui-material-progress:7.2.49
296
+ @nativescript-community/ui-material-ripple:7.2.49
297
+ @nativescript-community/ui-material-slider:7.2.49
298
+ @nativescript-community/ui-material-snackbar:7.2.49
299
+ @nativescript-community/ui-material-tabs:7.2.49
300
+ @nativescript-community/ui-material-textfield:7.2.49
301
+ @nativescript-community/ui-material-textview:7.2.49
302
+
303
+ # Popular standalone packages compromised
304
+ angulartics2:14.1.2
305
+ koa2-swagger-ui:5.11.1
306
+ koa2-swagger-ui:5.11.2
307
+ ngx-bootstrap:18.1.4
308
+ ngx-bootstrap:19.0.3
309
+ ngx-bootstrap:20.0.4
310
+ ngx-bootstrap:20.0.5
311
+ ngx-bootstrap:20.0.6
312
+ ngx-toastr:19.0.1
313
+ ngx-toastr:19.0.2
314
+
315
+ # Additional compromised packages from JFrog comprehensive list
316
+ @art-ws/db-context:2.0.21
317
+ @basic-ui-components-stc/basic-ui-components:1.0.5
318
+ @ctrl/ngx-codemirror:7.0.1
319
+ @ctrl/ngx-csv:6.0.1
320
+ @ctrl/ngx-emoji-mart:9.2.1
321
+ @ctrl/ngx-rightclick:4.0.1
322
+ @ctrl/qbittorrent:9.7.1
323
+ @ctrl/react-adsense:2.0.1
324
+ @ctrl/shared-torrent:6.3.1
325
+ @ctrl/torrent-file:4.1.1
326
+ @ctrl/ts-base32:4.0.1
327
+ @hestjs/core:0.2.1
328
+ @hestjs/cqrs:0.1.6
329
+ @hestjs/demo:0.1.2
330
+ @hestjs/eslint-config:0.1.2
331
+ @hestjs/logger:0.1.6
332
+ @hestjs/scalar:0.1.7
333
+ @hestjs/validation:0.1.6
334
+ @nativescript-community/arraybuffers:1.1.6
335
+ @nativescript-community/arraybuffers:1.1.7
336
+ @nativescript-community/arraybuffers:1.1.8
337
+ @nativescript-community/perms:3.0.5
338
+ @nativescript-community/perms:3.0.6
339
+ @nativescript-community/perms:3.0.7
340
+ @nativescript-community/perms:3.0.8
341
+ @nativescript-community/perms:3.0.9
342
+ @nativescript-community/sentry:4.6.43
343
+ @nativescript-community/text:1.6.10
344
+ @nativescript-community/text:1.6.11
345
+ @nativescript-community/text:1.6.12
346
+ @nativescript-community/text:1.6.9
347
+ @nativescript-community/typeorm:0.2.30
348
+ @nativescript-community/typeorm:0.2.31
349
+ @nativescript-community/typeorm:0.2.32
350
+ @nativescript-community/typeorm:0.2.33
351
+ @nativescript-community/ui-document-picker:1.1.27
352
+ @nativescript-community/ui-document-picker:1.1.28
353
+ @nativescript-community/ui-label:1.3.35
354
+ @nativescript-community/ui-label:1.3.36
355
+ @nativescript-community/ui-label:1.3.37
356
+ @nativescript-community/ui-material-bottom-navigation:7.2.72
357
+ @nativescript-community/ui-material-bottom-navigation:7.2.73
358
+ @nativescript-community/ui-material-bottom-navigation:7.2.74
359
+ @nativescript-community/ui-material-bottom-navigation:7.2.75
360
+ @nativescript-community/ui-material-core-tabs:7.2.72
361
+ @nativescript-community/ui-material-core-tabs:7.2.73
362
+ @nativescript-community/ui-material-core-tabs:7.2.74
363
+ @nativescript-community/ui-material-core-tabs:7.2.75
364
+ @nativescript-community/ui-material-core:7.2.72
365
+ @nativescript-community/ui-material-core:7.2.73
366
+ @nativescript-community/ui-material-core:7.2.74
367
+ @nativescript-community/ui-material-core:7.2.75
368
+ @nativescript-community/ui-material-ripple:7.2.72
369
+ @nativescript-community/ui-material-ripple:7.2.73
370
+ @nativescript-community/ui-material-ripple:7.2.74
371
+ @nativescript-community/ui-material-ripple:7.2.75
372
+ @nativescript-community/ui-material-tabs:7.2.72
373
+ @nativescript-community/ui-material-tabs:7.2.73
374
+ @nativescript-community/ui-material-tabs:7.2.74
375
+ @nativescript-community/ui-material-tabs:7.2.75
376
+ @nativescript-community/ui-pager:14.1.35
377
+ @nativescript-community/ui-pager:14.1.36
378
+ @nativescript-community/ui-pager:14.1.37
379
+ @nativescript-community/ui-pager:14.1.38
380
+ @nativescript-community/ui-pulltorefresh:2.5.4
381
+ @nativescript-community/ui-pulltorefresh:2.5.5
382
+ @nativescript-community/ui-pulltorefresh:2.5.6
383
+ @nativescript-community/ui-pulltorefresh:2.5.7
384
+ @nexe/config-manager:0.1.1
385
+ @nexe/eslint-config:0.1.1
386
+ @nexe/logger:0.1.3
387
+ @nstudio/xplat-utils:20.0.4
388
+ @nstudio/xplat-utils:20.0.7
389
+ @nstudio/xplat:20.0.4
390
+ @nstudio/xplat:20.0.5
391
+ @nstudio/xplat:20.0.6
392
+ @nstudio/xplat:20.0.7
393
+ @operato/board:9.0.35
394
+ @operato/board:9.0.47
395
+ @operato/board:9.0.48
396
+ @operato/board:9.0.49
397
+ @operato/board:9.0.50
398
+ @operato/board:9.0.51
399
+ @operato/graphql:9.0.47
400
+ @operato/graphql:9.0.48
401
+ @operato/graphql:9.0.49
402
+ @operato/graphql:9.0.50
403
+ @operato/graphql:9.0.51
404
+ @operato/help:9.0.47
405
+ @operato/help:9.0.48
406
+ @operato/help:9.0.49
407
+ @operato/help:9.0.50
408
+ @operato/help:9.0.51
409
+ @operato/input:9.0.47
410
+ @operato/input:9.0.48
411
+ @operato/popup:9.0.47
412
+ @operato/popup:9.0.48
413
+ @operato/popup:9.0.49
414
+ @operato/popup:9.0.50
415
+ @operato/popup:9.0.51
416
+ @operato/pull-to-refresh:9.0.35
417
+ @operato/pull-to-refresh:9.0.43
418
+ @operato/pull-to-refresh:9.0.44
419
+ @operato/pull-to-refresh:9.0.45
420
+ @operato/pull-to-refresh:9.0.46
421
+ @operato/pull-to-refresh:9.0.47
422
+ @operato/utils:9.0.47
423
+ @operato/utils:9.0.48
424
+ @operato/utils:9.0.49
425
+ @operato/utils:9.0.50
426
+ @operato/utils:9.0.51
427
+ @thangved/callback-window:1.1.4
428
+ @things-factory/attachment-base:9.0.42
429
+ @things-factory/attachment-base:9.0.51
430
+ @things-factory/attachment-base:9.0.52
431
+ @things-factory/attachment-base:9.0.53
432
+ @things-factory/attachment-base:9.0.54
433
+ @things-factory/attachment-base:9.0.55
434
+ @things-factory/auth-base:9.0.42
435
+ @things-factory/email-base:9.0.55
436
+ @things-factory/email-base:9.0.56
437
+ @things-factory/email-base:9.0.57
438
+ @things-factory/email-base:9.0.58
439
+ @things-factory/email-base:9.0.59
440
+ @things-factory/integration-base:9.0.42
441
+ @things-factory/integration-marketplace:9.0.42
442
+ @things-factory/shell:9.0.42
443
+ @things-factory/shell:9.0.43
444
+ @things-factory/shell:9.0.44
445
+ @things-factory/shell:9.0.45
446
+ @tnf-dev/api:1.0.8
447
+ @tnf-dev/core:1.0.8
448
+ @tnf-dev/js:1.0.8
449
+ @tnf-dev/mui:1.0.8
450
+ @tnf-dev/react:1.0.8
451
+ @ui-ux-gang/devextreme-angular-rpk:24.1.7
452
+ @ui-ux-gang/devextreme-rpk:24.1.7
453
+ @yoobic/design-system:6.5.17
454
+ @yoobic/jpeg-camera-es6:1.0.13
455
+ @yoobic/yobi:8.7.53
456
+ ace-colorpicker-rpk:0.0.14
457
+ airchief:0.3.1
458
+ airpilot:0.8.8
459
+ angulartics2:14.1.1
460
+ browser-webdriver-downloader:3.0.8
461
+ capacitor-notificationhandler:0.0.2
462
+ capacitor-notificationhandler:0.0.3
463
+ capacitor-plugin-healthapp:0.0.2
464
+ capacitor-plugin-healthapp:0.0.3
465
+ capacitor-plugin-ihealth:1.1.8
466
+ capacitor-plugin-ihealth:1.1.9
467
+ capacitor-plugin-vonage:1.0.2
468
+ capacitor-plugin-vonage:1.0.3
469
+ capacitorandroidpermissions:0.0.4
470
+ capacitorandroidpermissions:0.0.5
471
+ config-cordova:0.8.5
472
+ cordova-plugin-voxeet2:1.0.24
473
+ cordova-voxeet:1.0.32
474
+ create-hest-app:0.1.9
475
+ db-evo:1.1.4
476
+ db-evo:1.1.5
477
+ devextreme-angular-rpk:21.2.8
478
+ devextreme-rpk:21.2.8
479
+ ember-browser-services:5.0.2
480
+ ember-browser-services:5.0.3
481
+ ember-headless-form-yup:1.0.1
482
+ ember-headless-form:1.1.2
483
+ ember-headless-form:1.1.3
484
+ ember-headless-table:2.1.5
485
+ ember-headless-table:2.1.6
486
+ ember-url-hash-polyfill:1.0.12
487
+ ember-url-hash-polyfill:1.0.13
488
+ ember-velcro:2.2.1
489
+ ember-velcro:2.2.2
490
+ encounter-playground:0.0.2
491
+ encounter-playground:0.0.3
492
+ encounter-playground:0.0.4
493
+ eslint-config-crowdstrike-node:4.0.3
494
+ eslint-config-crowdstrike-node:4.0.4
495
+ eslint-config-crowdstrike:11.0.2
496
+ eslint-config-crowdstrike:11.0.3
497
+ eslint-config-teselagen:6.1.7
498
+ eslint-config-teselagen:6.1.8
499
+ globalize-rpk:1.7.4
500
+ graphql-sequelize-teselagen:5.3.8
501
+ graphql-sequelize-teselagen:5.3.9
502
+ html-to-base64-image:1.0.2
503
+ json-rules-engine-simplified:0.2.1
504
+ json-rules-engine-simplified:0.2.2
505
+ json-rules-engine-simplified:0.2.3
506
+ json-rules-engine-simplified:0.2.4
507
+ jumpgate:0.0.2
508
+ mcfly-semantic-release:1.3.1
509
+ mcp-knowledge-base:0.0.2
510
+ mcp-knowledge-graph:1.2.1
511
+ mobioffice-cli:1.0.3
512
+ monorepo-next:13.0.1
513
+ monorepo-next:13.0.2
514
+ mstate-angular:0.4.4
515
+ mstate-cli:0.4.7
516
+ mstate-dev-react:1.1.1
517
+ mstate-react:1.6.5
518
+ ng-imports-checker:0.0.10
519
+ ng-imports-checker:0.0.9
520
+ ng2-file-upload:7.0.2
521
+ ng2-file-upload:8.0.1
522
+ ng2-file-upload:8.0.2
523
+ ng2-file-upload:8.0.3
524
+ ng2-file-upload:9.0.1
525
+ ngx-bootstrap:19.0.4
526
+ ngx-bootstrap:20.0.3
527
+ ngx-color:10.0.1
528
+ ngx-ws:1.1.5
529
+ ngx-ws:1.1.6
530
+ oradm-to-gql:35.0.14
531
+ oradm-to-gql:35.0.15
532
+ oradm-to-sqlz:1.1.2
533
+ oradm-to-sqlz:1.1.3
534
+ oradm-to-sqlz:1.1.4
535
+ oradm-to-sqlz:1.1.5
536
+ ove-auto-annotate:0.0.10
537
+ ove-auto-annotate:0.0.9
538
+ pm2-gelf-json:1.0.4
539
+ pm2-gelf-json:1.0.5
540
+ printjs-rpk:1.6.1
541
+ react-complaint-image:0.0.32
542
+ react-complaint-image:0.0.33
543
+ react-complaint-image:0.0.34
544
+ react-jsonschema-form-conditionals:0.3.18
545
+ react-jsonschema-form-conditionals:0.3.19
546
+ react-jsonschema-form-conditionals:0.3.20
547
+ react-jsonschema-form-extras:1.0.1
548
+ react-jsonschema-form-extras:1.0.2
549
+ react-jsonschema-form-extras:1.0.3
550
+ react-jsonschema-rxnt-extras:0.4.6
551
+ react-jsonschema-rxnt-extras:0.4.7
552
+ react-jsonschema-rxnt-extras:0.4.8
553
+ react-jsonschema-rxnt-extras:0.4.9
554
+ remark-preset-lint-crowdstrike:4.0.1
555
+ remark-preset-lint-crowdstrike:4.0.2
556
+ rxnt-authentication:0.0.3
557
+ rxnt-authentication:0.0.4
558
+ rxnt-authentication:0.0.5
559
+ rxnt-healthchecks-nestjs:1.0.2
560
+ rxnt-healthchecks-nestjs:1.0.3
561
+ rxnt-healthchecks-nestjs:1.0.4
562
+ rxnt-kue:1.0.4
563
+ rxnt-kue:1.0.5
564
+ rxnt-kue:1.0.6
565
+ swc-plugin-component-annotate:1.9.1
566
+ tbssnch:1.0.2
567
+ teselagen-interval-tree:1.1.2
568
+ tg-client-query-builder:2.14.4
569
+ tg-client-query-builder:2.14.5
570
+ tg-redbird:1.3.1
571
+ tg-redbird:1.3.2
572
+ tg-seq-gen:1.0.10
573
+ tg-seq-gen:1.0.9
574
+ thangved-react-grid:1.0.3
575
+ ts-gaussian:3.0.5
576
+ ts-imports:1.0.1
577
+ ts-imports:1.0.2
578
+ tvi-cli:0.1.5
579
+ ve-bamreader:0.2.6
580
+ ve-bamreader:0.2.7
581
+ ve-editor:1.0.1
582
+ ve-editor:1.0.2
583
+ verror-extra:6.0.1
584
+ voip-callkit:1.0.2
585
+ voip-callkit:1.0.3
586
+ wdio-web-reporter:0.1.3
587
+ yargs-help-output:5.0.3
588
+ yoo-styles:6.0.326
package/gitignore ADDED
@@ -0,0 +1,36 @@
1
+ # Node.js
2
+ node_modules/
3
+
4
+ # OS junk
5
+ .DS_Store
6
+ Thumbs.db
7
+
8
+ # IDEs and editors
9
+ # VS Code
10
+ .vscode/
11
+ *.code-workspace
12
+
13
+ # IntelliJ / JetBrains IDEs
14
+ .idea/
15
+ *.iml
16
+
17
+ # Eclipse
18
+ .project
19
+ .classpath
20
+ .settings/
21
+
22
+ # NetBeans
23
+ nbproject/private/
24
+ build/
25
+
26
+ # Vim
27
+ *.swp
28
+ *.swo
29
+
30
+ # Emacs
31
+ *~
32
+ \#*\#
33
+
34
+ # Other backups
35
+ *.bak
36
+ *.tmp
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "hulud-party-scanner",
3
+ "version": "1.0.0",
4
+ "preferGlobal": true,
5
+ "bin": {
6
+ "hulud-party-scanner": "./scan.js"
7
+ },
8
+ "description": "Project integrity scanner for known vulnerabilities and suspicious patterns related to the Shai-Hulud supply-chain attack.",
9
+ "main": "scan.js",
10
+ "scripts": {
11
+ "scan": "node scan.js"
12
+ },
13
+ "author": "miguel.sngular",
14
+ "license": "ISC",
15
+ "repository": "https://github.com/migohe14/hulud-scanner"
16
+ }
package/scan.js ADDED
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const https = require('https');
4
+ const path = require('path');
5
+ const crypto = require('crypto');
6
+
7
+ // --- Configuration ---
8
+ const COMPROMISED_LIST_URL = "https://raw.githubusercontent.com/migohe14/hulud-scanner/refs/heads/main/compromised-libs.txt";
9
+ const MALICIOUS_HASH = "46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09";
10
+
11
+ // --- Console Colors ---
12
+ const colors = {
13
+ RED: '\x1b[31m',
14
+ GREEN: '\x1b[32m',
15
+ YELLOW: '\x1b[33m',
16
+ CYAN: '\x1b[36m',
17
+ BLUE: '\x1b[34m',
18
+ RESET: '\x1b[0m'
19
+ };
20
+
21
+ /**
22
+ * Downloads the list of compromised packages from GitHub.
23
+ * @returns {Promise<Set<string>>} A Set of packages in "name@version" format.
24
+ */
25
+ async function getCompromisedPackages() {
26
+ console.log(`${colors.CYAN}🌐 Downloading compromised packages list...${colors.RESET}`);
27
+ return new Promise((resolve, reject) => {
28
+ https.get(COMPROMISED_LIST_URL, (res) => {
29
+ let data = '';
30
+ res.on('data', (chunk) => { data += chunk; });
31
+ res.on('end', () => {
32
+ const packages = data
33
+ .split('\n')
34
+ .map(line => line.trim())
35
+ .filter(line => line && !line.startsWith('#')) // Ignore comments and empty lines
36
+ .map(line => line.replace(':', '@')) // Change 'pkg:1.0.0' to 'pkg@1.0.0'
37
+ .reduce((acc, line) => {
38
+ // Handle lines with multiple versions like 'pkg:1.0.0, 1.0.1'
39
+ const [name, versions] = line.split('@');
40
+ if (versions) {
41
+ versions.split(',').forEach(version => {
42
+ acc.add(`${name}@${version.trim()}`);
43
+ });
44
+ }
45
+ return acc;
46
+ }, new Set());
47
+ resolve(packages);
48
+ });
49
+ }).on('error', (err) => {
50
+ reject(new Error(`Failed to download list: ${err.message}`));
51
+ });
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Extracts all dependencies from a package-lock.json file.
57
+ * Supports v1/v2 (npm 6) and v2/v3 (npm 7+) formats.
58
+ * @param {string} lockfilePath - Path to the package-lock.json.
59
+ * @returns {Set<string>} A Set of local dependencies in "name@version" format.
60
+ */
61
+ function getLocalPackages(lockfilePath) {
62
+ console.log(`${colors.CYAN}πŸ“¦ Extracting dependencies from ${lockfilePath}...${colors.RESET}`);
63
+ if (!fs.existsSync(lockfilePath)) {
64
+ throw new Error(`File not found: ${lockfilePath}`);
65
+ }
66
+
67
+ const lockfile = JSON.parse(fs.readFileSync(lockfilePath, 'utf-8'));
68
+ const packages = new Set();
69
+
70
+ // Modern format (npm 7+), 'packages' key
71
+ if (lockfile.packages) {
72
+ console.log(`πŸ” Analyzing lockfile format v2/v3 (npm 7+)...`);
73
+ for (const [pkgPath, details] of Object.entries(lockfile.packages)) {
74
+ if (pkgPath && details.version) {
75
+ // La ruta es como "node_modules/express" o "" para el root.
76
+ const name = pkgPath.replace(/^node_modules\//, '');
77
+ if (name) { // Ignorar el paquete raΓ­z del proyecto
78
+ packages.add(`${name}@${details.version}`);
79
+ }
80
+ }
81
+ }
82
+ }
83
+ // Legacy format (npm 6), 'dependencies' key
84
+ else if (lockfile.dependencies) {
85
+ console.log(`πŸ” Analyzing lockfile format v1 (npm 6)...`);
86
+ const extractDeps = (deps) => {
87
+ if (!deps) return;
88
+ for (const [name, details] of Object.entries(deps)) {
89
+ if (details.version) {
90
+ packages.add(`${name}@${details.version}`);
91
+ }
92
+ // Recursively search in sub-dependencies
93
+ if (details.dependencies) {
94
+ extractDeps(details.dependencies);
95
+ }
96
+ }
97
+ };
98
+ extractDeps(lockfile.dependencies);
99
+ } else {
100
+ throw new Error('Unrecognized package-lock.json format.');
101
+ }
102
+
103
+ return packages;
104
+ }
105
+
106
+ /**
107
+ * Recursively scans a directory for files matching a known malicious hash.
108
+ * @param {string} directory - The directory to scan.
109
+ * @returns {string[]} A list of paths to malicious files.
110
+ */
111
+ function scanForMaliciousFiles(directory) {
112
+ console.log(`${colors.CYAN}πŸ” Scanning file signatures in ${directory}...${colors.RESET}`);
113
+ const maliciousFiles = [];
114
+ const filesToScan = [];
115
+
116
+ // Get all files recursively, ignoring node_modules and .git
117
+ function findFiles(dir) {
118
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
119
+ for (const entry of entries) {
120
+ const fullPath = path.join(dir, entry.name);
121
+ if (entry.isDirectory()) {
122
+ if (entry.name !== 'node_modules' && entry.name !== '.git') {
123
+ findFiles(fullPath);
124
+ }
125
+ } else if (entry.isFile()) {
126
+ filesToScan.push(fullPath);
127
+ }
128
+ }
129
+ }
130
+
131
+ findFiles(directory);
132
+
133
+ for (const file of filesToScan) {
134
+ const fileBuffer = fs.readFileSync(file);
135
+ const hashSum = crypto.createHash('sha256');
136
+ hashSum.update(fileBuffer);
137
+ const hex = hashSum.digest('hex');
138
+
139
+ if (hex === MALICIOUS_HASH) {
140
+ maliciousFiles.push(path.relative(directory, file));
141
+ }
142
+ }
143
+ return maliciousFiles;
144
+ }
145
+
146
+ /**
147
+ * Main function to orchestrate the scan.
148
+ */
149
+ async function main() {
150
+ try {
151
+ // Use the provided path or the current directory.
152
+ const targetPath = process.argv[2] || '.';
153
+ const projectRoot = path.resolve(targetPath);
154
+
155
+ if (!fs.existsSync(projectRoot) || !fs.statSync(projectRoot).isDirectory()) {
156
+ throw new Error(`Project directory not found: ${projectRoot}`);
157
+ }
158
+
159
+ console.log(`\n${colors.BLUE}--- Shai-Hulud Integrity Scanner (Node.js) ---${colors.RESET}`);
160
+ console.log(`Scanning project at: ${projectRoot}`);
161
+
162
+ // --- Vector 1: Dependency Analysis ---
163
+ let dependencyMatches = new Set();
164
+ const lockfilePath = path.join(projectRoot, 'package-lock.json');
165
+
166
+ if (fs.existsSync(lockfilePath)) {
167
+ const localPackages = getLocalPackages(lockfilePath);
168
+ const compromisedPackages = await getCompromisedPackages();
169
+ console.log(`${colors.CYAN}πŸ” Comparing dependencies...${colors.RESET}`);
170
+ for (const localPkg of localPackages) {
171
+ if (compromisedPackages.has(localPkg)) {
172
+ dependencyMatches.add(localPkg);
173
+ }
174
+ }
175
+ } else {
176
+ console.log(`${colors.YELLOW}⚠️ No package-lock.json found. Skipping dependency scan.${colors.RESET}`);
177
+ }
178
+
179
+ // --- Vector 2: File Signature Analysis ---
180
+ const fileMatches = scanForMaliciousFiles(projectRoot);
181
+
182
+ // --- Reporting ---
183
+ console.log('\n' + '-'.repeat(50));
184
+ let issuesFound = false;
185
+
186
+ if (fileMatches.length > 0) {
187
+ issuesFound = true;
188
+ console.log(`${colors.RED}🚨 CRITICAL RISK: Known Malware Signature Detected${colors.RESET}`);
189
+ fileMatches.forEach(match => {
190
+ console.log(` - File: ${colors.YELLOW}${match}${colors.RESET}`);
191
+ });
192
+ console.log('');
193
+ }
194
+
195
+ if (dependencyMatches.size > 0) {
196
+ issuesFound = true;
197
+ console.log(`${colors.RED}🚨 HIGH RISK: Compromised Package Versions Detected${colors.RESET}`);
198
+ dependencyMatches.forEach(match => {
199
+ console.log(` - ${colors.YELLOW}${match}${colors.RESET}`);
200
+ });
201
+ }
202
+
203
+ console.log('-'.repeat(50));
204
+ if (issuesFound) {
205
+ console.log(`${colors.RED}Scan complete. Actionable issues were found.${colors.RESET}`);
206
+ process.exit(2);
207
+ } else {
208
+ console.log(`${colors.GREEN}βœ… All good! No known integrity issues found.${colors.RESET}`);
209
+ }
210
+
211
+ } catch (error) {
212
+ console.error(`${colors.RED}❌ ERROR: ${error.message}${colors.RESET}`);
213
+ process.exit(1);
214
+ }
215
+ }
216
+
217
+ main();