Skip to content

Instantly share code, notes, and snippets.

@stevedylandev
Last active September 24, 2025 11:27
Show Gist options
  • Save stevedylandev/1ffc89b1e55263cb07efbaed9b21c1aa to your computer and use it in GitHub Desktop.
Save stevedylandev/1ffc89b1e55263cb07efbaed9b21c1aa to your computer and use it in GitHub Desktop.
Recursive scan in a project to check if malicious npm package versions from 090825 exploit might be installed
#!/bin/bash
# Script to check for vulnerable npm packages from supply chain attack
#
# To use simply copy and paste the contents into a file like `scan.sh` then run `bash scan.sh` in your project's root directory
echo "πŸ” Checking for vulnerable npm packages..."
echo "============================================="
# Define the vulnerable packages and versions
declare -A vulnerable_packages=(
["ansi-styles"]="6.2.2"
["debug"]="4.4.2"
["chalk"]="5.6.1"
["supports-color"]="10.2.1"
["strip-ansi"]="7.1.1"
["ansi-regex"]="6.2.1"
["wrap-ansi"]="9.0.1"
["color-convert"]="3.1.1"
["color-name"]="2.0.1"
["is-arrayish"]="0.3.3"
["slice-ansi"]="7.1.1"
["color"]="5.0.1"
["color-string"]="2.1.1"
["simple-swizzle"]="0.2.3"
["supports-hyperlinks"]="4.1.1"
["has-ansi"]="6.0.1"
["chalk-template"]="1.1.1"
["backslash"]="0.2.1"
)
found_vulnerable=false
# Check package.json files recursively
echo "Checking package.json files..."
find . -name "package.json" -not -path "*/node_modules/*" | while read package_file; do
echo "πŸ“„ Checking: $package_file"
for package in "${!vulnerable_packages[@]}"; do
version="${vulnerable_packages[$package]}"
# Check dependencies and devDependencies
if grep -q "\"$package\"" "$package_file"; then
echo "⚠️ Found $package in $package_file"
grep -n "\"$package\"" "$package_file"
fi
done
done
# Check package-lock.json files
echo ""
echo "Checking package-lock.json files for exact vulnerable versions..."
find . -name "package-lock.json" -not -path "*/node_modules/*" | while read lock_file; do
echo "πŸ”’ Checking: $lock_file"
for package in "${!vulnerable_packages[@]}"; do
version="${vulnerable_packages[$package]}"
# Look for exact version matches in lock file
if grep -q "\"$package\".*\"$version\"" "$lock_file" || grep -q "\"version\": \"$version\"" "$lock_file" | grep -B5 -A5 "\"$package\"" > /dev/null; then
echo "🚨 VULNERABLE: Found $package@$version in $lock_file"
found_vulnerable=true
fi
done
done
# Check yarn.lock if it exists
echo ""
if find . -name "yarn.lock" -not -path "*/node_modules/*" | grep -q .; then
echo "Checking yarn.lock files..."
find . -name "yarn.lock" -not -path "*/node_modules/*" | while read yarn_file; do
echo "🧢 Checking: $yarn_file"
for package in "${!vulnerable_packages[@]}"; do
version="${vulnerable_packages[$package]}"
if grep -q "^$package@.*$version" "$yarn_file"; then
echo "🚨 VULNERABLE: Found $package@$version in $yarn_file"
found_vulnerable=true
fi
done
done
fi
# Check pnpm-lock.yaml if it exists
echo ""
if find . -name "pnpm-lock.yaml" -not -path "*/node_modules/*" | grep -q .; then
echo "Checking pnpm-lock.yaml files..."
find . -name "pnpm-lock.yaml" -not -path "*/node_modules/*" | while read pnpm_file; do
echo "πŸ”§ Checking: $pnpm_file"
for package in "${!vulnerable_packages[@]}"; do
version="${vulnerable_packages[$package]}"
# pnpm lock files have format like: /package@version:
if grep -q "/$package@$version:" "$pnpm_file" || grep -q "/$package/$version" "$pnpm_file"; then
echo "🚨 VULNERABLE: Found $package@$version in $pnpm_file"
found_vulnerable=true
fi
done
done
fi
# Check bun.lockb if it exists
echo ""
if find . -name "bun.lockb" -not -path "*/node_modules/*" | grep -q .; then
echo "Checking bun.lockb files..."
find . -name "bun.lockb" -not -path "*/node_modules/*" | while read bun_file; do
echo "🍞 Checking: $bun_file"
for package in "${!vulnerable_packages[@]}"; do
version="${vulnerable_packages[$package]}"
# bun.lockb is a binary file, but we can try to search for the package@version pattern
# Note: This might not be 100% reliable due to binary format, but it's better than nothing
if strings "$bun_file" 2>/dev/null | grep -q "$package.*$version"; then
echo "🚨 VULNERABLE: Found $package@$version in $bun_file"
found_vulnerable=true
fi
done
done
fi
# Check currently installed packages if node_modules exists
echo ""
if [ -d "node_modules" ]; then
echo "Checking currently installed packages in node_modules..."
for package in "${!vulnerable_packages[@]}"; do
version="${vulnerable_packages[$package]}"
if [ -f "node_modules/$package/package.json" ]; then
installed_version=$(grep '"version"' "node_modules/$package/package.json" | sed 's/.*"version": "\([^"]*\)".*/\1/')
if [ "$installed_version" = "$version" ]; then
echo "🚨 VULNERABLE: $package@$version is currently installed"
found_vulnerable=true
else
echo "βœ… $package@$installed_version (safe version installed)"
fi
fi
done
fi
echo ""
echo "============================================="
if [ "$found_vulnerable" = true ]; then
echo "🚨 VULNERABLE PACKAGES DETECTED!"
echo "Please update your dependencies immediately and run audit commands for more details."
echo "Consider updating the affected packages or deleting lock files and reinstalling."
else
echo "βœ… No vulnerable versions detected in this scan."
echo "However, please also run audit commands for a comprehensive security check."
fi
echo ""
echo "πŸ’‘ Additional recommendations:"
echo " - Run package manager audit commands:"
echo " β€’ npm: 'npm audit'"
echo " β€’ yarn: 'yarn audit'"
echo " β€’ pnpm: 'pnpm audit'"
echo " β€’ bun: 'bun audit' (if available)"
echo " - Clear package manager caches:"
echo " β€’ npm: 'npm cache clean --force'"
echo " β€’ yarn: 'yarn cache clean'"
echo " β€’ pnpm: 'pnpm store prune'"
echo " β€’ bun: 'bun pm cache rm'"
echo " - Delete node_modules and lock files, then reinstall:"
echo " β€’ 'rm -rf node_modules && rm -f package-lock.json yarn.lock pnpm-lock.yaml bun.lockb'"
echo " β€’ Then: '[npm install|yarn|pnpm install|bun install]'"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment