Skip to content

Instantly share code, notes, and snippets.

@cgrothaus
Last active September 22, 2025 06:07
Show Gist options
  • Select an option

  • Save cgrothaus/11bbd556b193f5869aaf34bc0fc8f332 to your computer and use it in GitHub Desktop.

Select an option

Save cgrothaus/11bbd556b193f5869aaf34bc0fc8f332 to your computer and use it in GitHub Desktop.
Script to check for compromised npm packages in pnpm-lock.yaml (npm supply chain attack of September 2025)
#!/usr/bin/env zsh
# Script to check for compromised npm packages in monorepos using pnpm, grepping through pnpm-lock.yaml.
# Usage: zsh check-compromised-npm-packages-pnpm-lock.zsh [path-to-pnpm-lock.yaml]
#
# Background: news on supply chain attacks in npm packages of September 2025
# 1.
# - https://www.aikido.dev/blog/npm-debug-and-chalk-packages-compromised
# - https://news.ycombinator.com/item?id=45169794
# 2.
# - https://socket.dev/blog/tinycolor-supply-chain-attack-affects-40-packages
# 3.
# - https://www.ox.security/blog/npm-2-0-hack-40-npm-packages-hit-in-major-supply-chain-attack/
# - https://www.aikido.dev/blog/s1ngularity-nx-attackers-strike-again
# 4.
# - https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages
# Default to current directory's pnpm-lock.yaml if no argument provided
LOCKFILE="${1:-./pnpm-lock.yaml}"
if [[ ! -f "$LOCKFILE" ]]; then
echo "Error: pnpm-lock.yaml not found at $LOCKFILE"
exit 1
fi
# List of compromised packages and versions
# Format: package@version (like in pnpm-lock.yaml)
compromised=(
# first attack compromised packages:
"@duckdb/[email protected]"
"@duckdb/[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
# second attack compromised packages:
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
# third attack compromised packages:
"@ahmedhfarag/[email protected]"
"@ahmedhfarag/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@art-ws/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@crowdstrike/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@ctrl/[email protected]"
"@hestjs/[email protected]"
"@hestjs/[email protected]"
"@hestjs/[email protected]"
"@hestjs/[email protected]"
"@hestjs/[email protected]"
"@hestjs/[email protected]"
"@hestjs/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nativescript-community/[email protected]"
"@nexe/[email protected]"
"@nexe/[email protected]"
"@nexe/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@nstudio/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@thangved/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@tnf-dev/[email protected]"
"@tnf-dev/[email protected]"
"@tnf-dev/[email protected]"
"@tnf-dev/[email protected]"
"@tnf-dev/[email protected]"
"@ui-ux-gang/[email protected]"
"@yoobic/[email protected]"
"@yoobic/[email protected]"
"@yoobic/[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
# fourth article compromised packages:
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@operato/[email protected]"
"@rxap/[email protected]"
"@rxap/[email protected]"
"@teriyakibomb/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@teselagen/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"@things-factory/[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
)
echo "Checking $LOCKFILE for potentially compromised packages..."
echo "Total packages to check: ${#compromised[@]}"
echo ""
found_count=0
found_packages=()
# Loop through each package and search for it
for package in "${compromised[@]}"; do
# Use -F for fixed string matching (faster than regex)
if grep -q -F "$package" "$LOCKFILE"; then
echo "❌ FOUND: $package"
found_count=$((found_count + 1))
found_packages+=("$package")
fi
done
echo ""
echo "Summary:"
echo "--------"
echo "Packages checked: ${#compromised[@]}"
echo "Potentially compromised packages found: $found_count"
if [[ $found_count -gt 0 ]]; then
echo ""
echo "Found packages:"
for pkg in "${found_packages[@]}"; do
echo " - $pkg"
done
echo ""
echo "⚠️ WARNING: Consider updating or removing these packages immediately!"
exit 1
else
echo ""
echo "✅ No compromised packages found in your lockfile."
exit 0
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment