Created
November 24, 2025 17:09
-
-
Save MatthewCallis/9e12800405269d4a766f9b711ff26d17 to your computer and use it in GitHub Desktop.
Check for affected packages during a NPM security issue,
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
| #!/bin/bash | |
| # Script to check if any affected packages are installed in package-lock.json files on macOS | |
| # This checks against a list of 288 potentially vulnerable npm packages | |
| # Recursively searches for package-lock.json files from the root directory | |
| # Based on https://gist.github.com/considine/2098a0426b212f27feb6fb3b4d714660 by @considine | |
| # https://news.ycombinator.com/item?id=46032539 | |
| # https://www.aikido.dev/blog/shai-hulud-strikes-again-hitting-zapier-ensdomains | |
| # https://helixguard.ai/blog/malicious-sha1hulud-2025-11-24 | |
| # Color codes for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' # No Color | |
| # List of affected packages | |
| AFFECTED_PACKAGES=( | |
| "@actbase/css-to-react-native-transform" | |
| "@actbase/node-server" | |
| "@actbase/react-absolute" | |
| "@actbase/react-daum-postcode" | |
| "@actbase/react-kakaosdk" | |
| "@actbase/react-native-actionsheet" | |
| "@actbase/react-native-devtools" | |
| "@actbase/react-native-fast-image" | |
| "@actbase/react-native-kakao-channel" | |
| "@actbase/react-native-kakao-navi" | |
| "@actbase/react-native-less-transformer" | |
| "@actbase/react-native-naver-login" | |
| "@actbase/react-native-simple-video" | |
| "@actbase/react-native-tiktok" | |
| "@alaan/s2s-auth" | |
| "@aryanhussain/my-angular-lib" | |
| "@asyncapi/avro-schema-parser" | |
| "@asyncapi/bundler" | |
| "@asyncapi/cli" | |
| "@asyncapi/converter" | |
| "@asyncapi/diff" | |
| "@asyncapi/dotnet-rabbitmq-template" | |
| "@asyncapi/edavisualiser" | |
| "@asyncapi/generator" | |
| "@asyncapi/generator-components" | |
| "@asyncapi/generator-helpers" | |
| "@asyncapi/generator-react-sdk" | |
| "@asyncapi/go-watermill-template" | |
| "@asyncapi/html-template" | |
| "@asyncapi/java-spring-cloud-stream-template" | |
| "@asyncapi/java-spring-template" | |
| "@asyncapi/java-template" | |
| "@asyncapi/keeper" | |
| "@asyncapi/markdown-template" | |
| "@asyncapi/modelina" | |
| "@asyncapi/modelina-cli" | |
| "@asyncapi/multi-parser" | |
| "@asyncapi/nodejs-template" | |
| "@asyncapi/nodejs-ws-template" | |
| "@asyncapi/nunjucks-filters" | |
| "@asyncapi/openapi-schema-parser" | |
| "@asyncapi/optimizer" | |
| "@asyncapi/parser" | |
| "@asyncapi/php-template" | |
| "@asyncapi/problem" | |
| "@asyncapi/protobuf-schema-parser" | |
| "@asyncapi/python-paho-template" | |
| "@asyncapi/react-component" | |
| "@asyncapi/server-api" | |
| "@asyncapi/specs" | |
| "@asyncapi/web-component" | |
| "@caretive/caret-cli" | |
| "@ensdomains/address-encoder" | |
| "@ensdomains/blacklist" | |
| "@ensdomains/buffer" | |
| "@ensdomains/ccip-read-dns-gateway" | |
| "@ensdomains/ccip-read-router" | |
| "@ensdomains/ccip-read-worker-viem" | |
| "@ensdomains/content-hash" | |
| "@ensdomains/curvearithmetics" | |
| "@ensdomains/cypress-metamask" | |
| "@ensdomains/dnsprovejs" | |
| "@ensdomains/dnssec-oracle-anchors" | |
| "@ensdomains/dnssecoraclejs" | |
| "@ensdomains/durin-middleware" | |
| "@ensdomains/ens-archived-contracts" | |
| "@ensdomains/ens-avatar" | |
| "@ensdomains/ens-validation" | |
| "@ensdomains/eth-ens-namehash" | |
| "@ensdomains/hackathon-registrar" | |
| "@ensdomains/hardhat-chai-matchers-viem" | |
| "@ensdomains/hardhat-toolbox-viem-extended" | |
| "@ensdomains/mock" | |
| "@ensdomains/name-wrapper" | |
| "@ensdomains/offchain-resolver-contracts" | |
| "@ensdomains/react-ens-address" | |
| "@ensdomains/renewal" | |
| "@ensdomains/renewal-widget" | |
| "@ensdomains/reverse-records" | |
| "@ensdomains/server-analytics" | |
| "@ensdomains/solsha1" | |
| "@ensdomains/subdomain-registrar" | |
| "@ensdomains/test-utils" | |
| "@ensdomains/thorin" | |
| "@ensdomains/ui" | |
| "@ensdomains/unicode-confusables" | |
| "@ensdomains/unruggable-gateways" | |
| "@ensdomains/vite-plugin-i18next-loader" | |
| "@ensdomains/web3modal" | |
| "@kvytech/cli" | |
| "@kvytech/components" | |
| "@kvytech/medusa-plugin-announcement" | |
| "@kvytech/medusa-plugin-management" | |
| "@kvytech/medusa-plugin-newsletter" | |
| "@kvytech/medusa-plugin-product-reviews" | |
| "@kvytech/web" | |
| "@louisle2/cortex-js" | |
| "@markvivanco/app-version-checker" | |
| "@mcp-use/cli" | |
| "@mcp-use/inspector" | |
| "@mcp-use/mcp-use" | |
| "@mparpaillon/connector-parse" | |
| "@mparpaillon/imagesloaded" | |
| "@mparpaillon/page" | |
| "@orbitgtbelgium/mapbox-gl-draw-scale-rotate-mode" | |
| "@orbitgtbelgium/orbit-components" | |
| "@orbitgtbelgium/time-slider" | |
| "@posthog/agent" | |
| "@posthog/ai" | |
| "@posthog/automatic-cohorts-plugin" | |
| "@posthog/cli" | |
| "@posthog/core" | |
| "@posthog/currency-normalization-plugin" | |
| "@posthog/customerio-plugin" | |
| "@posthog/databricks-plugin" | |
| "@posthog/event-sequence-timer-plugin" | |
| "@posthog/first-time-event-tracker" | |
| "@posthog/geoip-plugin" | |
| "@posthog/github-release-tracking-plugin" | |
| "@posthog/gitub-star-sync-plugin" | |
| "@posthog/hedgehog-mode" | |
| "@posthog/ingestion-alert-plugin" | |
| "@posthog/kinesis-plugin" | |
| "@posthog/maxmind-plugin" | |
| "@posthog/nextjs" | |
| "@posthog/nextjs-config" | |
| "@posthog/nuxt" | |
| "@posthog/pagerduty-plugin" | |
| "@posthog/piscina" | |
| "@posthog/plugin-contrib" | |
| "@posthog/plugin-unduplicates" | |
| "@posthog/react-rrweb-player" | |
| "@posthog/rrdom" | |
| "@posthog/rrweb" | |
| "@posthog/rrweb-player" | |
| "@posthog/rrweb-record" | |
| "@posthog/rrweb-snapshot" | |
| "@posthog/rrweb-utils" | |
| "@posthog/sendgrid-plugin" | |
| "@posthog/siphash" | |
| "@posthog/snowflake-export-plugin" | |
| "@posthog/taxonomy-plugin" | |
| "@posthog/twitter-followers-plugin" | |
| "@posthog/twilio-plugin" | |
| "@posthog/url-normalizer-plugin" | |
| "@posthog/variance-plugin" | |
| "@posthog/web-dev-server" | |
| "@posthog/wizard" | |
| "@postman/aether-icons" | |
| "@postman/csv-parse" | |
| "@postman/final-node-keytar" | |
| "@postman/mcp-ui-client" | |
| "@postman/node-keytar" | |
| "@postman/pm-bin-linux-x64" | |
| "@postman/pm-bin-macos-arm64" | |
| "@postman/pm-bin-macos-x64" | |
| "@postman/pm-bin-windows-x64" | |
| "@postman/postman-collection-fork" | |
| "@postman/postman-mcp-cli" | |
| "@postman/postman-mcp-server" | |
| "@postman/pretty-ms" | |
| "@postman/secret-scanner-wasm" | |
| "@postman/tunnel-agent" | |
| "@postman/wdio-allure-reporter" | |
| "@postman/wdio-junit-reporter" | |
| "@quick-start-soft/quick-document-translator" | |
| "@quick-start-soft/quick-git-clean-markdown" | |
| "@quick-start-soft/quick-markdown" | |
| "@quick-start-soft/quick-markdown-compose" | |
| "@quick-start-soft/quick-markdown-image" | |
| "@quick-start-soft/quick-task-refine" | |
| "@seung-ju/next" | |
| "@seung-ju/openapi-generator" | |
| "@seung-ju/react-hooks" | |
| "@seung-ju/react-native-action-sheet" | |
| "@strapbuild/react-native-date-time-picker" | |
| "@strapbuild/react-native-perspective-image-cropper" | |
| "@strapbuild/react-native-perspective-image-cropper-2" | |
| "@strapbuild/react-native-perspective-image-cropper-poojan31" | |
| "@trigo/atrix" | |
| "@trigo/atrix-acl" | |
| "@trigo/atrix-elasticsearch" | |
| "@trigo/atrix-mongoose" | |
| "@trigo/atrix-orientdb" | |
| "@trigo/atrix-postgres" | |
| "@trigo/atrix-pubsub" | |
| "@trigo/atrix-redis" | |
| "@trigo/atrix-soap" | |
| "@trigo/bool-expressions" | |
| "@trigo/eslint-config-trigo" | |
| "@trigo/fsm" | |
| "@trigo/hapi-auth-signedlink" | |
| "@trigo/jsdt" | |
| "@trigo/keycloak-api" | |
| "@trigo/node-soap" | |
| "@trigo/pathfinder-ui-css" | |
| "@trigo/trigo-hapijs" | |
| "@zapier/ai-actions" | |
| "@zapier/ai-actions-react" | |
| "@zapier/babel-preset-zapier" | |
| "@zapier/browserslist-config-zapier" | |
| "@zapier/eslint-plugin-zapier" | |
| "@zapier/mcp-integration" | |
| "@zapier/secret-scrubber" | |
| "@zapier/spectral-api-ruleset" | |
| "@zapier/stubtree" | |
| "@zapier/zapier-sdk" | |
| "asyncapi-preview" | |
| "atrix" | |
| "atrix-mongoose" | |
| "axios-builder" | |
| "bool-expressions" | |
| "bytecode-checker-cli" | |
| "calc-loan-interest" | |
| "capacitor-plugin-apptrackingios" | |
| "capacitor-plugin-purchase" | |
| "capacitor-plugin-scgssigninwithgoogle" | |
| "capacitor-purchase-history" | |
| "capacitor-voice-recorder-wav" | |
| "claude-token-updater" | |
| "cpu-instructions" | |
| "create-glee-app" | |
| "create-hardhat3-app" | |
| "create-mcp-use-app" | |
| "crypto-addr-codec" | |
| "devstart-cli" | |
| "discord-bot-server" | |
| "dotnet-template" | |
| "esbuild-plugin-eta" | |
| "esbuild-plugin-httpfile" | |
| "eslint-config-trigo" | |
| "eslint-config-zeallat-base" | |
| "ethereum-ens" | |
| "evm-checkcode-cli" | |
| "exact-ticker" | |
| "expo-audio-session" | |
| "gate-evm-check-code2" | |
| "gate-evm-tools-test" | |
| "github-action-for-generator" | |
| "go-template" | |
| "iron-shield-miniapp" | |
| "jan-browser" | |
| "korea-administrative-area-geo-json-util" | |
| "lite-serper-mcp-server" | |
| "manual-billing-system-miniapp-api" | |
| "mcp-use" | |
| "medusa-plugin-announcement" | |
| "medusa-plugin-momo" | |
| "medusa-plugin-product-reviews-kvy" | |
| "medusa-plugin-zalopay" | |
| "n8n-nodes-tmdb" | |
| "open2internet" | |
| "orbit-boxicons" | |
| "orbit-nebula-draw-tools" | |
| "orbit-nebula-editor" | |
| "orbit-soap" | |
| "poper-react-sdk" | |
| "posthog-docusaurus" | |
| "posthog-node" | |
| "posthog-plugin-hello-world" | |
| "posthog-react-native" | |
| "posthog-react-native-session-replay" | |
| "react-element-prompt-inspector" | |
| "react-library-setup" | |
| "react-native-use-modal" | |
| "react-native-worklet-functions" | |
| "redux-forge" | |
| "redux-router-kit" | |
| "rollup-plugin-httpfile" | |
| "scgs-capacitor-subscribe" | |
| "scgsffcreator" | |
| "shinhan-limit-scrap" | |
| "skills-use" | |
| "test-foundry-app" | |
| "test-hardhat-app" | |
| "token.js-fork" | |
| "trigo-react-app" | |
| "typeorm-orbit" | |
| "vite-plugin-httpfile" | |
| "web-types-lit" | |
| "zapier-async-storage" | |
| "zapier-platform-cli" | |
| "zapier-platform-core" | |
| "zapier-platform-legacy-scripting-runner" | |
| "zapier-platform-schema" | |
| "zapier-scripts" | |
| "zuper-cli" | |
| "zuper-stream" | |
| ) | |
| echo "==================================================" | |
| echo " Affected NPM Packages Security Checker" | |
| echo "==================================================" | |
| echo "" | |
| echo "Checking ${#AFFECTED_PACKAGES[@]} potentially vulnerable packages..." | |
| echo "" | |
| # Find all package-lock.json files recursively from root | |
| LOCK_FILES=($(find . -name "package-lock.json" -type f 2>/dev/null)) | |
| if [ ${#LOCK_FILES[@]} -eq 0 ]; then | |
| echo -e "${RED}Error: No package-lock.json files found${NC}" | |
| echo "Please run this script from the root of your project" | |
| exit 1 | |
| fi | |
| echo "Found ${#LOCK_FILES[@]} package-lock.json file(s):" | |
| for lock_file in "${LOCK_FILES[@]}"; do | |
| echo " - $lock_file" | |
| done | |
| echo "" | |
| # Initialize counters and tracking | |
| found_count=0 | |
| found_packages=() | |
| found_locations=() | |
| # Check each package in each lock file | |
| for package in "${AFFECTED_PACKAGES[@]}"; do | |
| package_found=false | |
| locations="" | |
| for lock_file in "${LOCK_FILES[@]}"; do | |
| # Check for package in package-lock.json format (JSON structure) | |
| # Matches both "node_modules/package-name" and "package-name" entries | |
| if grep -q "\"${package}\"" "$lock_file" 2>/dev/null || grep -q "\"node_modules/${package}\"" "$lock_file" 2>/dev/null; then | |
| if [ "$package_found" = false ]; then | |
| package_found=true | |
| found_packages+=("$package") | |
| ((found_count++)) | |
| fi | |
| if [ -z "$locations" ]; then | |
| locations="$lock_file" | |
| else | |
| locations="$locations, $lock_file" | |
| fi | |
| fi | |
| done | |
| if [ "$package_found" = true ]; then | |
| found_locations+=("$locations") | |
| fi | |
| done | |
| # Display results | |
| echo "==================================================" | |
| if [ $found_count -eq 0 ]; then | |
| echo -e "${GREEN}✓ CLEAN - No affected packages found!${NC}" | |
| echo "" | |
| echo "Your project does not use any of the 288 affected packages." | |
| else | |
| echo -e "${RED}⚠ WARNING - Found ${found_count} affected package(s):${NC}" | |
| echo "" | |
| for ((i=0; i<${#found_packages[@]}; i++)); do | |
| echo -e " ${RED}✗${NC} ${found_packages[$i]}" | |
| echo -e " Found in: ${found_locations[$i]}" | |
| done | |
| echo "" | |
| echo -e "${YELLOW}Recommendation:${NC}" | |
| echo " Review these packages and consider removing or replacing them." | |
| fi | |
| echo "==================================================" | |
| echo "" | |
| echo "Total packages checked: ${#AFFECTED_PACKAGES[@]}" | |
| echo "Packages found: $found_count" | |
| echo "Packages not found: $((${#AFFECTED_PACKAGES[@]} - found_count))" | |
| echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment