Skip to content

Instantly share code, notes, and snippets.

@MatthewCallis
Created November 24, 2025 17:09
Show Gist options
  • Select an option

  • Save MatthewCallis/9e12800405269d4a766f9b711ff26d17 to your computer and use it in GitHub Desktop.

Select an option

Save MatthewCallis/9e12800405269d4a766f9b711ff26d17 to your computer and use it in GitHub Desktop.
Check for affected packages during a NPM security issue,
#!/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