|
import { readFileSync } from 'node:fs'; |
|
import { readdir } from 'node:fs/promises'; |
|
import path from 'path'; |
|
|
|
if (process.argv.length <= 2) { |
|
console.error(`Usage: node --permission --allow-fs-read ... ${process.argv[1]} "<directory>,<directory2>,..."`); |
|
console.error(`Example: node --permission --allow-fs-read c:/ ${process.argv[1]} "c:/repos,c:/more/repos"`); |
|
process.exit(1); |
|
} |
|
const scanDirs = process.argv[2].split(',').map(dir => dir.trim()); |
|
|
|
console.log(`Starting scan for malicious npm packages in the following directories: ${scanDirs.join(', ')}`) |
|
console.log(`Be sure to set node --allow-fs-read=... for all dirs, so nodejs can read it`); |
|
|
|
let counter = 0 |
|
|
|
const maliciousPackages = { |
|
// https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages |
|
'@ahmedhfarag/ngx-perfect-scrollbar': {"versions":["20.0.20"]}, |
|
'@ahmedhfarag/ngx-virtual-scroller': {"versions":["4.0.4"]}, |
|
'@art-ws/common': {"versions":["2.0.28"]}, |
|
'@art-ws/config-eslint': {"versions":["2.0.4","2.0.5"]}, |
|
'@art-ws/config-ts': {"versions":["2.0.7","2.0.8"]}, |
|
'@art-ws/db-context': {"versions":["2.0.24"]}, |
|
'@art-ws/di-node': {"versions":["2.0.13"]}, |
|
'@art-ws/di': {"versions":["2.0.28","2.0.32"]}, |
|
'@art-ws/eslint': {"versions":["1.0.5","1.0.6"]}, |
|
'@art-ws/fastify-http-server': {"versions":["2.0.24","2.0.27"]}, |
|
'@art-ws/http-server': {"versions":["2.0.21","2.0.25"]}, |
|
'@art-ws/openapi': {"versions":["0.1.12","0.1.9"]}, |
|
'@art-ws/package-base': {"versions":["1.0.5","1.0.6"]}, |
|
'@art-ws/prettier': {"versions":["1.0.5","1.0.6"]}, |
|
'@art-ws/slf': {"versions":["2.0.15","2.0.22"]}, |
|
'@art-ws/ssl-info': {"versions":["1.0.10","1.0.9"]}, |
|
'@art-ws/web-app': {"versions":["1.0.3","1.0.4"]}, |
|
'@crowdstrike/commitlint': {"versions":["8.1.1","8.1.2"]}, |
|
'@crowdstrike/falcon-shoelace': {"versions":["0.4.1","0.4.2"]}, |
|
'@crowdstrike/foundry-js': {"versions":["0.19.1","0.19.2"]}, |
|
'@crowdstrike/glide-core': {"versions":["0.34.2","0.34.3"]}, |
|
'@crowdstrike/logscale-dashboard': {"versions":["1.205.1","1.205.2"]}, |
|
'@crowdstrike/logscale-file-editor': {"versions":["1.205.1","1.205.2"]}, |
|
'@crowdstrike/logscale-parser-edit': {"versions":["1.205.1","1.205.2"]}, |
|
'@crowdstrike/logscale-search': {"versions":["1.205.1","1.205.2"]}, |
|
'@crowdstrike/tailwind-toucan-base': {"versions":["5.0.1","5.0.2"]}, |
|
'@ctrl/deluge': {"versions":["7.2.1","7.2.2"]}, |
|
'@ctrl/golang-template': {"versions":["1.4.2","1.4.3"]}, |
|
'@ctrl/magnet-link': {"versions":["4.0.3","4.0.4"]}, |
|
'@ctrl/ngx-codemirror': {"versions":["7.0.1","7.0.2"]}, |
|
'@ctrl/ngx-csv': {"versions":["6.0.1","6.0.2"]}, |
|
'@ctrl/ngx-emoji-mart': {"versions":["9.2.1","9.2.2"]}, |
|
'@ctrl/ngx-rightclick': {"versions":["4.0.1","4.0.2"]}, |
|
'@ctrl/qbittorrent': {"versions":["9.7.1","9.7.2"]}, |
|
'@ctrl/react-adsense': {"versions":["2.0.1","2.0.2"]}, |
|
'@ctrl/shared-torrent': {"versions":["6.3.1","6.3.2"]}, |
|
'@ctrl/tinycolor': {"versions":["4.1.1","4.1.2"]}, |
|
'@ctrl/torrent-file': {"versions":["4.1.1","4.1.2"]}, |
|
'@ctrl/transmission': {"versions":["7.3.1"]}, |
|
'@ctrl/ts-base32': {"versions":["4.0.1","4.0.2"]}, |
|
'@hestjs/core': {"versions":["0.2.1"]}, |
|
'@hestjs/cqrs': {"versions":["0.1.6"]}, |
|
'@hestjs/demo': {"versions":["0.1.2"]}, |
|
'@hestjs/eslint-config': {"versions":["0.1.2"]}, |
|
'@hestjs/logger': {"versions":["0.1.6"]}, |
|
'@hestjs/scalar': {"versions":["0.1.7"]}, |
|
'@hestjs/validation': {"versions":["0.1.6"]}, |
|
'@nativescript-community/arraybuffers': {"versions":["1.1.6","1.1.7","1.1.8"]}, |
|
'@nativescript-community/gesturehandler': {"versions":["2.0.35"]}, |
|
'@nativescript-community/perms': {"versions":["3.0.5","3.0.6","3.0.7","3.0.8","3.0.9"]}, |
|
'@nativescript-community/sentry': {"versions":["4.6.43"]}, |
|
'@nativescript-community/sqlite': {"versions":["3.5.2","3.5.3","3.5.4","3.5.5"]}, |
|
'@nativescript-community/text': {"versions":["1.6.10","1.6.11","1.6.12","1.6.13","1.6.9"]}, |
|
'@nativescript-community/typeorm': {"versions":["0.2.30","0.2.31","0.2.32","0.2.33"]}, |
|
'@nativescript-community/ui-collectionview': {"versions":["6.0.6"]}, |
|
'@nativescript-community/ui-document-picker': {"versions":["1.1.27","1.1.28"]}, |
|
'@nativescript-community/ui-drawer': {"versions":["0.1.30"]}, |
|
'@nativescript-community/ui-image': {"versions":["4.5.6"]}, |
|
'@nativescript-community/ui-label': {"versions":["1.3.35","1.3.36","1.3.37"]}, |
|
'@nativescript-community/ui-material-bottom-navigation': {"versions":["7.2.72","7.2.73","7.2.74","7.2.75"]}, |
|
'@nativescript-community/ui-material-bottomsheet': {"versions":["7.2.72"]}, |
|
'@nativescript-community/ui-material-core-tabs': {"versions":["7.2.72","7.2.73","7.2.74","7.2.75","7.2.76"]}, |
|
'@nativescript-community/ui-material-core': {"versions":["7.2.72","7.2.73","7.2.74","7.2.75","7.2.76"]}, |
|
'@nativescript-community/ui-material-ripple': {"versions":["7.2.72","7.2.73","7.2.74","7.2.75"]}, |
|
'@nativescript-community/ui-material-tabs': {"versions":["7.2.72","7.2.73","7.2.74","7.2.75"]}, |
|
'@nativescript-community/ui-pager': {"versions":["14.1.36","14.1.37","14.1.38"]}, |
|
'@nativescript-community/ui-pulltorefresh': {"versions":["2.5.4","2.5.5","2.5.6","2.5.7"]}, |
|
'@nexe/config-manager': {"versions":["0.1.1"]}, |
|
'@nexe/eslint-config': {"versions":["0.1.1"]}, |
|
'@nexe/logger': {"versions":["0.1.3"]}, |
|
'@nstudio/angular': {"versions":["20.0.4","20.0.5","20.0.6"]}, |
|
'@nstudio/focus': {"versions":["20.0.4","20.0.5","20.0.6"]}, |
|
'@nstudio/nativescript-checkbox': {"versions":["2.0.6","2.0.7","2.0.8","2.0.9"]}, |
|
'@nstudio/nativescript-loading-indicator': {"versions":["5.0.1","5.0.2","5.0.3","5.0.4"]}, |
|
'@nstudio/ui-collectionview': {"versions":["5.1.11","5.1.12","5.1.13","5.1.14"]}, |
|
'@nstudio/web-angular': {"versions":["20.0.4"]}, |
|
'@nstudio/web': {"versions":["20.0.4"]}, |
|
'@nstudio/xplat-utils': {"versions":["20.0.5","20.0.6","20.0.7"]}, |
|
'@nstudio/xplat': {"versions":["20.0.5","20.0.6","20.0.7"]}, |
|
'@operato/board': {"versions":["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","9.0.47","9.0.48","9.0.49","9.0.50","9.0.51"]}, |
|
'@operato/data-grist': {"versions":["9.0.29","9.0.35","9.0.36","9.0.37"]}, |
|
'@operato/graphql': {"versions":["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","9.0.47","9.0.48","9.0.49","9.0.50","9.0.51"]}, |
|
'@operato/headroom': {"versions":["9.0.2","9.0.35","9.0.36","9.0.37"]}, |
|
'@operato/help': {"versions":["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","9.0.47","9.0.48","9.0.49","9.0.50","9.0.51"]}, |
|
'@operato/i18n': {"versions":["9.0.35","9.0.36","9.0.37"]}, |
|
'@operato/input': {"versions":["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","9.0.47","9.0.48"]}, |
|
'@operato/layout': {"versions":["9.0.35","9.0.36","9.0.37"]}, |
|
'@operato/popup': {"versions":["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","9.0.47","9.0.48","9.0.49","9.0.50","9.0.51"]}, |
|
'@operato/pull-to-refresh': {"versions":["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","9.0.47"]}, |
|
'@operato/shell': {"versions":["9.0.22","9.0.35","9.0.36","9.0.37","9.0.38","9.0.39"]}, |
|
'@operato/styles': {"versions":["9.0.2","9.0.35","9.0.36","9.0.37"]}, |
|
'@operato/utils': {"versions":["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","9.0.47","9.0.48","9.0.49","9.0.50","9.0.51"]}, |
|
'@rxap/ngx-bootstrap': {"versions":["19.0.3","19.0.4"]}, |
|
'@teriyakibomb/ember-velcro': {"versions":["2.2.1"]}, |
|
'@teselagen/bio-parsers': {"versions":["0.4.30"]}, |
|
'@teselagen/bounce-loader': {"versions":["0.3.16","0.3.17"]}, |
|
'@teselagen/file-utils': {"versions":["0.3.22"]}, |
|
'@teselagen/liquibase-tools': {"versions":["0.4.1"]}, |
|
'@teselagen/ove': {"versions":["0.7.40"]}, |
|
'@teselagen/range-utils': {"versions":["0.3.14","0.3.15"]}, |
|
'@teselagen/react-list': {"versions":["0.8.19","0.8.20"]}, |
|
'@teselagen/react-table': {"versions":["6.10.19","6.10.20","6.10.22"]}, |
|
'@teselagen/sequence-utils': {"versions":["0.3.34"]}, |
|
'@teselagen/ui': {"versions":["0.9.10"]}, |
|
'@thangved/callback-window': {"versions":["1.1.4"]}, |
|
'@things-factory/attachment-base': {"versions":["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","9.0.53","9.0.54","9.0.55"]}, |
|
'@things-factory/auth-base': {"versions":["9.0.42","9.0.43","9.0.44","9.0.45"]}, |
|
'@things-factory/email-base': {"versions":["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","9.0.53","9.0.54","9.0.55","9.0.56","9.0.57","9.0.58","9.0.59"]}, |
|
'@things-factory/env': {"versions":["9.0.42","9.0.43","9.0.44","9.0.45"]}, |
|
'@things-factory/integration-base': {"versions":["9.0.42","9.0.43","9.0.44","9.0.45"]}, |
|
'@things-factory/integration-marketplace': {"versions":["9.0.43","9.0.44","9.0.45"]}, |
|
'@things-factory/shell': {"versions":["9.0.42","9.0.43","9.0.44","9.0.45"]}, |
|
'@tnf-dev/api': {"versions":["1.0.8"]}, |
|
'@tnf-dev/core': {"versions":["1.0.8"]}, |
|
'@tnf-dev/js': {"versions":["1.0.8"]}, |
|
'@tnf-dev/mui': {"versions":["1.0.8"]}, |
|
'@tnf-dev/react': {"versions":["1.0.8"]}, |
|
'@ui-ux-gang/devextreme-angular-rpk': {"versions":["24.1.7"]}, |
|
'@yoobic/design-system': {"versions":["6.5.17"]}, |
|
'@yoobic/jpeg-camera-es6': {"versions":["1.0.13"]}, |
|
'@yoobic/yobi': {"versions":["8.7.53"]}, |
|
'airchief': {"versions":["0.3.1"]}, |
|
'airpilot': {"versions":["0.8.8"]}, |
|
'angulartics2': {"versions":["14.1.1","14.1.2"]}, |
|
'another-shai': {"versions":["1.0.1"]}, |
|
'browser-webdriver-downloader': {"versions":["3.0.8"]}, |
|
'capacitor-notificationhandler': {"versions":["0.0.2","0.0.3"]}, |
|
'capacitor-plugin-healthapp': {"versions":["0.0.2","0.0.3"]}, |
|
'capacitor-plugin-ihealth': {"versions":["1.1.8","1.1.9"]}, |
|
'capacitor-plugin-vonage': {"versions":["1.0.2","1.0.3"]}, |
|
'capacitorandroidpermissions': {"versions":["0.0.4","0.0.5"]}, |
|
'config-cordova': {"versions":["0.8.5"]}, |
|
'cordova-plugin-voxeet2': {"versions":["1.0.24"]}, |
|
'cordova-voxeet': {"versions":["1.0.32"]}, |
|
'create-hest-app': {"versions":["0.1.9"]}, |
|
'db-evo': {"versions":["1.1.4","1.1.5"]}, |
|
'devextreme-angular-rpk': {"versions":["21.2.8"]}, |
|
'ember-browser-services': {"versions":["5.0.2","5.0.3"]}, |
|
'ember-headless-form-yup': {"versions":["1.0.1"]}, |
|
'ember-headless-form': {"versions":["1.1.2","1.1.3"]}, |
|
'ember-headless-table': {"versions":["2.1.5","2.1.6"]}, |
|
'ember-url-hash-polyfill': {"versions":["1.0.12","1.0.13"]}, |
|
'ember-velcro': {"versions":["2.2.1","2.2.2"]}, |
|
'encounter-playground': {"versions":["0.0.2","0.0.3","0.0.4","0.0.5"]}, |
|
'eslint-config-crowdstrike-node': {"versions":["4.0.3","4.0.4"]}, |
|
'eslint-config-crowdstrike': {"versions":["11.0.2","11.0.3"]}, |
|
'eslint-config-teselagen': {"versions":["6.1.7","6.1.8"]}, |
|
'globalize-rpk': {"versions":["1.7.4"]}, |
|
'graphql-sequelize-teselagen': {"versions":["5.3.8","5.3.9"]}, |
|
'html-to-base64-image': {"versions":["1.0.2"]}, |
|
'json-rules-engine-simplified': {"versions":["0.2.1","0.2.4"]}, |
|
'jumpgate': {"versions":["0.0.2"]}, |
|
'koa2-swagger-ui': {"versions":["5.11.1","5.11.2"]}, |
|
'mcfly-semantic-release': {"versions":["1.3.1"]}, |
|
'mcp-knowledge-base': {"versions":["0.0.2"]}, |
|
'mcp-knowledge-graph': {"versions":["1.2.1"]}, |
|
'mobioffice-cli': {"versions":["1.0.3"]}, |
|
'monorepo-next': {"versions":["13.0.1","13.0.2"]}, |
|
'mstate-angular': {"versions":["0.4.4"]}, |
|
'mstate-cli': {"versions":["0.4.7"]}, |
|
'mstate-dev-react': {"versions":["1.1.1"]}, |
|
'mstate-react': {"versions":["1.6.5"]}, |
|
'ng2-file-upload': {"versions":["7.0.2","7.0.3","8.0.1","8.0.2","8.0.3","9.0.1"]}, |
|
'ngx-bootstrap': {"versions":["18.1.4","19.0.3","19.0.4","20.0.3","20.0.4","20.0.5"]}, |
|
'ngx-color': {"versions":["10.0.1","10.0.2"]}, |
|
'ngx-toastr': {"versions":["19.0.1","19.0.2"]}, |
|
'ngx-trend': {"versions":["8.0.1"]}, |
|
'ngx-ws': {"versions":["1.1.5","1.1.6"]}, |
|
'oradm-to-gql': {"versions":["35.0.14","35.0.15"]}, |
|
'oradm-to-sqlz': {"versions":["1.1.2"]}, |
|
'ove-auto-annotate': {"versions":["0.0.10","0.0.9"]}, |
|
'pm2-gelf-json': {"versions":["1.0.4","1.0.5"]}, |
|
'printjs-rpk': {"versions":["1.6.1"]}, |
|
'react-complaint-image': {"versions":["0.0.32","0.0.35"]}, |
|
'react-jsonschema-form-conditionals': {"versions":["0.3.18","0.3.21"]}, |
|
'react-jsonschema-form-extras': {"versions":["1.0.4"]}, |
|
'react-jsonschema-rxnt-extras': {"versions":["0.4.9"]}, |
|
'remark-preset-lint-crowdstrike': {"versions":["4.0.1","4.0.2"]}, |
|
'rxnt-authentication': {"versions":["0.0.3","0.0.4","0.0.5","0.0.6"]}, |
|
'rxnt-healthchecks-nestjs': {"versions":["1.0.2","1.0.3","1.0.4","1.0.5"]}, |
|
'rxnt-kue': {"versions":["1.0.4","1.0.5","1.0.6","1.0.7"]}, |
|
'swc-plugin-component-annotate': {"versions":["1.9.1","1.9.2"]}, |
|
'tbssnch': {"versions":["1.0.2"]}, |
|
'teselagen-interval-tree': {"versions":["1.1.2"]}, |
|
'tg-client-query-builder': {"versions":["2.14.4","2.14.5"]}, |
|
'tg-redbird': {"versions":["1.3.1","1.3.2"]}, |
|
'tg-seq-gen': {"versions":["1.0.10","1.0.9"]}, |
|
'thangved-react-grid': {"versions":["1.0.3"]}, |
|
'ts-gaussian': {"versions":["3.0.5","3.0.6"]}, |
|
'ts-imports': {"versions":["1.0.1","1.0.2"]}, |
|
'tvi-cli': {"versions":["0.1.5"]}, |
|
've-bamreader': {"versions":["0.2.6","0.2.7"]}, |
|
've-editor': {"versions":["1.0.1","1.0.2"]}, |
|
'verror-extra': {"versions":["6.0.1"]}, |
|
'voip-callkit': {"versions":["1.0.2","1.0.3"]}, |
|
'wdio-web-reporter': {"versions":["0.1.3"]}, |
|
'yargs-help-output': {"versions":["5.0.3"]}, |
|
'yoo-styles': {"versions":["6.0.326"]}, |
|
|
|
// https://jfrog.com/blog/new-compromised-packages-in-largest-npm-attack-in-history/ |
|
'backslash': { versions: [ '0.2.1' ] }, |
|
'chalk-template': { versions: [ '1.1.1' ] }, |
|
'supports-hyperlinks': { versions: [ '4.1.1' ] }, |
|
'has-ansi': { versions: [ '6.0.1' ] }, |
|
'simple-swizzle': { versions: [ '0.2.3' ] }, |
|
'color-string': { versions: [ '2.1.1' ] }, |
|
'error-ex': { versions: [ '1.3.3' ] }, |
|
'color-name': { versions: [ '2.0.1' ] }, |
|
'is-arrayish': { versions: [ '0.3.3' ] }, |
|
'slice-ansi': { versions: [ '7.1.1' ] }, |
|
'color-convert': { versions: [ '3.1.1' ] }, |
|
'wrap-ansi': { versions: [ '9.0.1' ] }, |
|
'ansi-regex': { versions: [ '6.2.1' ] }, |
|
'supports-color': { versions: [ '10.2.1' ] }, |
|
'strip-ansi': { versions: [ '7.1.1' ] }, |
|
'chalk': { versions: [ '5.6.1' ] }, |
|
'debug': { versions: [ '4.4.2' ] }, |
|
'ansi-styles': { versions: [ '6.2.2' ] }, |
|
'proto-tinker-wc': { versions: [ '0.1.87' ] }, |
|
'prebid': { versions: [ '10.9.1', '10.9.2' ] }, |
|
'@coveops/abi': { versions: [ '2.0.1' ] }, |
|
'duckdb': { versions: [ '1.3.3' ] }, |
|
'@duckdb/node-bindings': { versions: [ '1.3.3' ] }, |
|
'@duckdb/duckdb-wasm': { versions: [ '1.29.2' ] }, |
|
'@duckdb/node-api': { versions: [ '1.3.3' ] }, |
|
|
|
// https://socket.dev/blog/npm-is-package-hijacked-in-expanding-supply-chain-attack |
|
'eslint-config-prettier': { versions: [ '8.10.1', '9.1.1', '10.1.6', '10.1.7' ] }, |
|
'eslint-plugin-prettier': { versions: [ '4.2.2', '4.2.3' ] }, |
|
'synckit': { versions: [ '0.11.9' ] }, |
|
'@pkgr/core': { versions: [ '0.2.8' ] }, |
|
'napi-postinstall': { versions: [ '0.3.1' ] }, |
|
'got-fetch': { versions: [ '5.1.11', '5.1.12' ] }, |
|
'is': { versions: [ '3.3.1', '5.0.0' ] }, |
|
|
|
// https://github.com/nrwl/nx/security/advisories/GHSA-cxm3-wv7p-598c |
|
'@nx/devkit': { versions: [ '21.5.0', '20.9.0' ] }, |
|
'@nx/enterprise-cloud': { versions: [ '3.2.0' ] }, |
|
'@nx/eslint': { versions: [ '21.5.0' ] }, |
|
'@nx/js': { versions: [ '21.5.0', '20.9.0' ] }, |
|
'@nx/key': { versions: [ '3.2.0' ] }, |
|
'@nx/node': { versions: [ '21.5.0', '20.9.0' ] }, |
|
'@nx/workspace': { versions: [ '21.5.0', '20.9.0' ] }, |
|
'nx': { versions: [ '21.5.0', '20.9.0', '20.10.0', '21.6.0', '20.11.0', '21.7.0', '21.8.0', '20.12.0' ] }, |
|
} |
|
|
|
const evilVersions = []; |
|
const knownEvilVersionsButNotUsingThem = []; |
|
const noKnownEvilVersions = []; |
|
const skippedNoNameOrVersion = []; |
|
const parsingErrors = []; |
|
|
|
const findPackageJsons = async (dir) => { |
|
const list = await readdir(dir, { recursive: true }); |
|
return list.filter(file => file.endsWith('package.json')).map(file => path.resolve(dir, file)); |
|
} |
|
|
|
const checkFile = (filePath) => { |
|
const data = readFileSync(filePath, 'utf8') |
|
counter++; |
|
if (counter % 500 === 0) { |
|
console.log(`Checked ${counter} package.json files...`); |
|
} |
|
|
|
let content |
|
try { |
|
content = JSON.parse(data); |
|
} catch(err) { |
|
parsingErrors.push(`Error parsing ${filePath}: ${err.message}`); |
|
return |
|
} |
|
|
|
if (!content.name || !content.version) { |
|
skippedNoNameOrVersion.push(`Skipping ${filePath} as it does not have a name or version field`); |
|
return |
|
} |
|
|
|
if (!maliciousPackages[content.name.trim()]) { |
|
noKnownEvilVersions.push(`Checked ${filePath}, no issues found in ${content.name}@${content.version}.`) |
|
return |
|
} |
|
|
|
const maliciousVersions = maliciousPackages[content.name].versions |
|
if (maliciousVersions.includes(content.version.trim())) { |
|
evilVersions.push(`☠️ Malicious package found: ${content.name}@${content.version} in ${filePath}`) |
|
} else { |
|
knownEvilVersionsButNotUsingThem.push(`Unaffected ${content.name}@${content.version} in ${filePath}. Evil versions are: ${maliciousVersions.join(', ')}`) |
|
} |
|
}; |
|
|
|
for (const scanDir of scanDirs) { |
|
console.log(`Scanning directory: ${scanDir}`); |
|
const packageJsonFiles = await Promise.all(await findPackageJsons(scanDir)); |
|
packageJsonFiles.map(file => checkFile(file)); |
|
} |
|
|
|
|
|
console.log(`Scan complete. Checked a total of ${counter} package.json files in the folders ${scanDirs.join(', ')}`); |
|
console.log(`${skippedNoNameOrVersion.length} files were skipped as they did not have a name or version field`); |
|
console.log(`${parsingErrors.length} files were skipped as they do not contain valid JSON content: ${JSON.stringify(parsingErrors, null, 2)}`); |
|
console.log(`${noKnownEvilVersions.length} dont have any known malicious versions`); |
|
console.log(`${knownEvilVersionsButNotUsingThem.length} of your files are known, that they were affected once, but you use an unaffected version, as far as we know. Here is the list: ${JSON.stringify(knownEvilVersionsButNotUsingThem.sort(), null, 2)} `); |
|
|
|
if (evilVersions.length === 0) { |
|
console.log(`We did not find malicious packages by inspecting your local package.jsons inside the folders ${scanDirs.join(', ')}. ⚠️ But be be aware, we only checked for a small set of known malicious packages. There might be others, that we dont know yet`); |
|
} else { |
|
console.log(`⚠️⚠️⚠️⚠️⚠️`); |
|
console.log(`THATS NOT GOOD. We found ${evilVersions.length} malicious packages in your package.json files! Please remove them ASAP and consider talk to your ISM team! Here is the list: ${JSON.stringify(evilVersions.sort(), null, 2)}`); |
|
} |