Created
September 17, 2025 13:29
-
-
Save Cadienvan/c4f858ae6be8167e62ded89dc7f9579c to your computer and use it in GitHub Desktop.
Package Lock Checker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @ahmedhfarag/ngx-perfect-scrollbar | |
| @ahmedhfarag/ngx-virtual-scroller | |
| @art-ws/common | |
| @art-ws/config-eslint | |
| @art-ws/config-ts | |
| @art-ws/db-context | |
| @art-ws/di-node | |
| @art-ws/di | |
| @art-ws/eslint | |
| @art-ws/fastify-http-server | |
| @art-ws/http-server | |
| @art-ws/openapi | |
| @art-ws/package-base | |
| @art-ws/prettier | |
| @art-ws/slf | |
| @art-ws/ssl-info | |
| @art-ws/web-app | |
| @crowdstrike/commitlint | |
| @crowdstrike/falcon-shoelace | |
| @crowdstrike/foundry-js | |
| @crowdstrike/glide-core | |
| @crowdstrike/logscale-dashboard | |
| @crowdstrike/logscale-file-editor | |
| @crowdstrike/logscale-parser-edit | |
| @crowdstrike/logscale-search | |
| @crowdstrike/tailwind-toucan-base | |
| @ctrl/deluge | |
| @ctrl/golang-template | |
| @ctrl/magnet-link | |
| @ctrl/ngx-codemirror | |
| @ctrl/ngx-csv | |
| @ctrl/ngx-emoji-mart | |
| @ctrl/ngx-rightclick | |
| @ctrl/qbittorrent | |
| @ctrl/react-adsense | |
| @ctrl/shared-torrent | |
| @ctrl/tinycolor | |
| @ctrl/torrent-file | |
| @ctrl/transmission | |
| @ctrl/ts-base32 | |
| @hestjs/core | |
| @hestjs/cqrs | |
| @hestjs/demo | |
| @hestjs/eslint-config | |
| @hestjs/logger | |
| @hestjs/scalar | |
| @hestjs/validation | |
| @nativescript-community/arraybuffers | |
| @nativescript-community/gesturehandler | |
| @nativescript-community/perms | |
| @nativescript-community/sentry | |
| @nativescript-community/sqlite | |
| @nativescript-community/text | |
| @nativescript-community/typeorm | |
| @nativescript-community/ui-collectionview | |
| @nativescript-community/ui-document-picker | |
| @nativescript-community/ui-drawer | |
| @nativescript-community/ui-image | |
| @nativescript-community/ui-label | |
| @nativescript-community/ui-material-bottom-navigation | |
| @nativescript-community/ui-material-bottomsheet | |
| @nativescript-community/ui-material-core-tabs | |
| @nativescript-community/ui-material-core | |
| @nativescript-community/ui-material-ripple | |
| @nativescript-community/ui-material-tabs | |
| @nativescript-community/ui-pager | |
| @nativescript-community/ui-pulltorefresh | |
| @nexe/config-manager | |
| @nexe/eslint-config | |
| @nexe/logger | |
| @nstudio/angular | |
| @nstudio/focus | |
| @nstudio/nativescript-checkbox | |
| @nstudio/nativescript-loading-indicator | |
| @nstudio/ui-collectionview | |
| @nstudio/web-angular | |
| @nstudio/web | |
| @nstudio/xplat-utils | |
| @nstudio/xplat | |
| @operato/board | |
| @operato/data-grist | |
| @operato/graphql | |
| @operato/headroom | |
| @operato/help | |
| @operato/i18n | |
| @operato/input | |
| @operato/layout | |
| @operato/popup | |
| @operato/pull-to-refresh | |
| @operato/shell | |
| @operato/styles | |
| @operato/utils | |
| @teselagen/bio-parsers | |
| @teselagen/bounce-loader | |
| @teselagen/file-utils | |
| @teselagen/liquibase-tools | |
| @teselagen/ove | |
| @teselagen/range-utils | |
| @teselagen/react-list | |
| @teselagen/react-table | |
| @teselagen/sequence-utils | |
| @teselagen/ui | |
| @thangved/callback-window | |
| @things-factory/attachment-base | |
| @things-factory/auth-base | |
| @things-factory/email-base | |
| @things-factory/env | |
| @things-factory/integration-base | |
| @things-factory/integration-marketplace | |
| @things-factory/shell | |
| @tnf-dev/api | |
| @tnf-dev/core | |
| @tnf-dev/js | |
| @tnf-dev/mui | |
| @tnf-dev/react | |
| @ui-ux-gang/devextreme-angular-rpk | |
| @yoobic/design-system | |
| @yoobic/jpeg-camera-es6 | |
| @yoobic/yobi | |
| airchief | |
| airpilot | |
| angulartics2 | |
| browser-webdriver-downloader | |
| capacitor-notificationhandler | |
| capacitor-plugin-healthapp | |
| capacitor-plugin-ihealth | |
| capacitor-plugin-vonage | |
| capacitorandroidpermissions | |
| config-cordova | |
| cordova-plugin-voxeet2 | |
| cordova-voxeet | |
| create-hest-app | |
| db-evo | |
| devextreme-angular-rpk | |
| ember-browser-services | |
| ember-headless-form-yup | |
| ember-headless-form | |
| ember-headless-table | |
| ember-url-hash-polyfill | |
| ember-velcro | |
| encounter-playground | |
| eslint-config-crowdstrike-node | |
| eslint-config-crowdstrike | |
| eslint-config-teselagen | |
| globalize-rpk | |
| graphql-sequelize-teselagen | |
| html-to-base64-image | |
| json-rules-engine-simplified | |
| jumpgate | |
| koa2-swagger-ui | |
| mcfly-semantic-release | |
| mcp-knowledge-base | |
| mcp-knowledge-graph | |
| mobioffice-cli | |
| monorepo-next | |
| mstate-angular | |
| mstate-cli | |
| mstate-dev-react | |
| mstate-react | |
| ng2-file-upload | |
| ngx-bootstrap | |
| ngx-color | |
| ngx-toastr | |
| ngx-trend | |
| ngx-ws | |
| oradm-to-gql | |
| oradm-to-sqlz | |
| ove-auto-annotate | |
| pm2-gelf-json | |
| printjs-rpk | |
| react-complaint-image | |
| react-jsonschema-form-conditionals | |
| react-jsonschema-form-extras | |
| react-jsonschema-rxnt-extras | |
| remark-preset-lint-crowdstrike | |
| rxnt-authentication | |
| rxnt-healthchecks-nestjs | |
| rxnt-kue | |
| swc-plugin-component-annotate | |
| tbssnch | |
| teselagen-interval-tree | |
| tg-client-query-builder | |
| tg-redbird | |
| tg-seq-gen | |
| thangved-react-grid | |
| ts-gaussian | |
| ts-imports | |
| tvi-cli | |
| ve-bamreader | |
| ve-editor | |
| verror-extra | |
| voip-callkit | |
| wdio-web-reporter | |
| yargs-help-output | |
| yoo-styles |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env node | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| /** | |
| * Reads and parses the list of compromised packages | |
| * @returns {Set<string>} Set of compromised package names | |
| */ | |
| function loadCompromisedPackages() { | |
| try { | |
| const listPath = path.join(__dirname, 'list.txt'); | |
| const content = fs.readFileSync(listPath, 'utf8'); | |
| // Split by lines and filter out empty lines | |
| const packages = content.split('\n') | |
| .map(line => line.trim()) | |
| .filter(line => line.length > 0); | |
| return new Set(packages); | |
| } catch (error) { | |
| console.error('Error reading compromised packages list:', error.message); | |
| process.exit(1); | |
| } | |
| } | |
| /** | |
| * Recursively extracts all package names from package-lock.json dependencies | |
| * @param {object} dependencies - Dependencies object from package-lock.json | |
| * @param {Set<string>} packageNames - Set to collect package names | |
| */ | |
| function extractPackageNames(dependencies, packageNames) { | |
| if (!dependencies) return; | |
| for (const [packageName, packageInfo] of Object.entries(dependencies)) { | |
| packageNames.add(packageName); | |
| // Recursively check nested dependencies | |
| if (packageInfo.dependencies) { | |
| extractPackageNames(packageInfo.dependencies, packageNames); | |
| } | |
| } | |
| } | |
| /** | |
| * Parses package-lock.json and returns all package names | |
| * @param {string} lockFilePath - Path to package-lock.json | |
| * @returns {Set<string>} Set of all package names in the lock file | |
| */ | |
| function parsePackageLock(lockFilePath) { | |
| try { | |
| const content = fs.readFileSync(lockFilePath, 'utf8'); | |
| const lockData = JSON.parse(content); | |
| const packageNames = new Set(); | |
| // Handle both v1 and v2+ package-lock.json formats | |
| if (lockData.dependencies) { | |
| // v1 format | |
| extractPackageNames(lockData.dependencies, packageNames); | |
| } else if (lockData.packages) { | |
| // v2+ format | |
| for (const [packagePath, packageInfo] of Object.entries(lockData.packages)) { | |
| // Skip the root package (empty string key) | |
| if (packagePath === '') continue; | |
| // Extract package name from path (remove node_modules/ prefix and nested paths) | |
| const packageName = packagePath | |
| .replace(/^node_modules\//, '') | |
| .split('/node_modules/')[0]; | |
| packageNames.add(packageName); | |
| } | |
| } | |
| return packageNames; | |
| } catch (error) { | |
| console.error('Error parsing package-lock.json:', error.message); | |
| process.exit(1); | |
| } | |
| } | |
| /** | |
| * Main function to check package-lock.json against compromised packages | |
| * @param {string} lockFilePath - Path to package-lock.json file | |
| */ | |
| function checkPackageLock(lockFilePath) { | |
| console.log(`Checking ${lockFilePath} for compromised packages...`); | |
| // Verify the lock file exists | |
| if (!fs.existsSync(lockFilePath)) { | |
| console.error(`Error: package-lock.json not found at ${lockFilePath}`); | |
| process.exit(1); | |
| } | |
| // Load compromised packages list | |
| const compromisedPackages = loadCompromisedPackages(); | |
| console.log(`Loaded ${compromisedPackages.size} compromised packages to check against`); | |
| // Parse package-lock.json | |
| const installedPackages = parsePackageLock(lockFilePath); | |
| console.log(`Found ${installedPackages.size} packages in lock file`); | |
| // Check for compromised packages | |
| const foundCompromised = []; | |
| for (const packageName of installedPackages) { | |
| if (compromisedPackages.has(packageName)) { | |
| foundCompromised.push(packageName); | |
| } | |
| } | |
| // Report results | |
| if (foundCompromised.length === 0) { | |
| console.log('✅ SUCCESS: No compromised packages found in the lock file!'); | |
| process.exit(0); | |
| } else { | |
| console.log(`❌ DANGER: Found ${foundCompromised.length} compromised package(s):`); | |
| foundCompromised.forEach(pkg => { | |
| console.log(` - ${pkg}`); | |
| }); | |
| console.log('\n⚠️ RECOMMENDATION: Remove these packages immediately!'); | |
| process.exit(1); | |
| } | |
| } | |
| // CLI interface | |
| function main() { | |
| const args = process.argv.slice(2); | |
| if (args.length === 0 || args.includes('--help') || args.includes('-h')) { | |
| console.log(`Usage: node index.js <path-to-package-lock.json> | |
| Description: | |
| Checks a package-lock.json file against a list of known compromised packages. | |
| Arguments: | |
| <path-to-package-lock.json> Path to the package-lock.json file to check | |
| Options: | |
| --help, -h Show this help message | |
| Examples: | |
| node index.js ./package-lock.json | |
| node index.js /path/to/project/package-lock.json | |
| Exit codes: | |
| 0 No compromised packages found | |
| 1 Compromised packages found or error occurred`); | |
| process.exit(0); | |
| } | |
| const lockFilePath = path.resolve(args[0]); | |
| checkPackageLock(lockFilePath); | |
| } | |
| // Run the script | |
| if (require.main === module) { | |
| main(); | |
| } | |
| module.exports = { | |
| loadCompromisedPackages, | |
| parsePackageLock, | |
| checkPackageLock | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment