Skip to content

Instantly share code, notes, and snippets.

@Bedrovelsen
Created May 12, 2026 22:11
Show Gist options
  • Select an option

  • Save Bedrovelsen/5274572de970e4f1cdd872af59aac8dd to your computer and use it in GitHub Desktop.

Select an option

Save Bedrovelsen/5274572de970e4f1cdd872af59aac8dd to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
PROJECT_PATH="${1:-.}"
cd "$PROJECT_PATH"
PROJECT_PATH=$(pwd)
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
BAD_PKGS="$TMPDIR/bad_pkgs.txt"
COMPROMISED_PKGS="$TMPDIR/compromised.txt"
MALICIOUS_FILES="$TMPDIR/malicious_files.txt"
SUSPICIOUS_DEPS="$TMPDIR/suspicious.txt"
LOCKFILE_MATCHES="$TMPDIR/lockfile.txt"
> "$COMPROMISED_PKGS"
> "$MALICIOUS_FILES"
> "$SUSPICIOUS_DEPS"
> "$LOCKFILE_MATCHES"
cat > "$BAD_PKGS" << 'EOF'
@tanstack/history@1.161.9
@tanstack/history@1.161.12
@tanstack/react-router@1.169.5
@tanstack/react-router@1.169.8
@tanstack/router-core@1.169.5
@tanstack/router-core@1.169.8
@tanstack/router-utils@1.161.11
@tanstack/router-utils@1.161.14
@tanstack/router-plugin@1.167.38
@tanstack/router-plugin@1.167.41
@tanstack/virtual-file-routes@1.161.10
@tanstack/virtual-file-routes@1.161.13
@tanstack/router-generator@1.166.45
@tanstack/router-generator@1.166.48
@tanstack/start-server-core@1.167.33
@tanstack/start-server-core@1.167.36
@tanstack/start-client-core@1.168.5
@tanstack/start-client-core@1.168.8
@tanstack/start-storage-context@1.166.38
@tanstack/start-storage-context@1.166.41
@tanstack/start-plugin-core@1.169.23
@tanstack/start-plugin-core@1.169.26
@tanstack/react-start-server@1.166.55
@tanstack/react-start-server@1.166.58
@tanstack/react-start-client@1.166.51
@tanstack/react-start-client@1.166.54
@tanstack/start-fn-stubs@1.161.9
@tanstack/start-fn-stubs@1.161.12
@tanstack/react-start@1.167.68
@tanstack/react-start@1.167.71
@tanstack/react-start-rsc@0.0.47
@tanstack/react-start-rsc@0.0.50
@mistralai/mistralai@2.2.2
@mistralai/mistralai@2.2.3
@mistralai/mistralai@2.2.4
@tanstack/react-router-devtools@1.166.16
@tanstack/react-router-devtools@1.166.19
@tanstack/router-devtools-core@1.167.6
@tanstack/router-devtools-core@1.167.9
@tanstack/router-devtools@1.166.16
@tanstack/router-devtools@1.166.19
@tanstack/router-ssr-query-core@1.168.3
@tanstack/router-ssr-query-core@1.168.6
@tanstack/react-router-ssr-query@1.166.15
@tanstack/react-router-ssr-query@1.166.18
@tanstack/router-cli@1.166.46
@tanstack/router-cli@1.166.49
@tanstack/zod-adapter@1.166.12
@tanstack/zod-adapter@1.166.15
@tanstack/eslint-plugin-router@1.161.9
@tanstack/router-vite-plugin@1.166.53
@tanstack/router-vite-plugin@1.166.56
@tanstack/nitro-v2-vite-plugin@1.154.12
@tanstack/nitro-v2-vite-plugin@1.154.15
@mistralai/mistralai-gcp@1.7.1
@mistralai/mistralai-gcp@1.7.2
@mistralai/mistralai-gcp@1.7.3
@tanstack/solid-router@1.169.5
@tanstack/solid-router@1.169.8
@tanstack/solid-start@1.167.65
@tanstack/solid-start@1.167.68
@tanstack/solid-start-client@1.166.50
@tanstack/solid-start-client@1.166.53
@tanstack/solid-start-server@1.166.54
@tanstack/solid-start-server@1.166.57
@tanstack/solid-router-devtools@1.166.16
@tanstack/solid-router-devtools@1.166.19
@tanstack/start-static-server-functions@1.166.44
@tanstack/start-static-server-functions@1.166.47
@tanstack/vue-router@1.169.5
@tanstack/vue-router@1.169.8
@uipath/apollo-react@4.24.5
@tanstack/solid-router-ssr-query@1.166.15
@tanstack/solid-router-ssr-query@1.166.18
safe-action@0.8.3
safe-action@0.8.4
@tanstack/valibot-adapter@1.166.12
@tanstack/valibot-adapter@1.166.15
@tanstack/vue-start@1.167.61
@tanstack/vue-start@1.167.64
@uipath/apollo-wind@2.16.2
@uipath/cli@1.0.1
@tanstack/vue-start-server@1.166.50
@tanstack/vue-start-server@1.166.53
@squawk/types@0.8.2
@squawk/types@0.8.3
@squawk/types@0.8.4
@uipath/rpa-tool@0.9.5
@squawk/mcp@0.9.1
@squawk/mcp@0.9.2
@squawk/mcp@0.9.3
@squawk/mcp@0.9.4
@tanstack/vue-start-client@1.166.46
@tanstack/vue-start-client@1.166.49
@squawk/weather@0.5.6
@squawk/weather@0.5.7
@squawk/weather@0.5.8
@squawk/weather@0.5.9
@squawk/airspace@0.8.1
@squawk/airspace@0.8.2
@squawk/airspace@0.8.3
@squawk/airspace@0.8.4
@squawk/icao-registry-data@0.8.4
@squawk/icao-registry-data@0.8.5
@squawk/icao-registry-data@0.8.6
@squawk/icao-registry-data@0.8.7
@tanstack/arktype-adapter@1.166.12
@tanstack/arktype-adapter@1.166.15
@squawk/flightplan@0.5.2
@squawk/flightplan@0.5.3
@squawk/flightplan@0.5.4
@squawk/flightplan@0.5.5
@squawk/airports@0.6.2
@squawk/airports@0.6.3
@squawk/airports@0.6.4
@squawk/airports@0.6.5
@mesadev/sdk@0.28.3
@squawk/geo@0.4.4
@squawk/geo@0.4.5
@squawk/geo@0.4.6
@squawk/geo@0.4.7
@mesadev/rest@0.28.3
@squawk/procedure-data@0.7.3
@squawk/procedure-data@0.7.4
@squawk/procedure-data@0.7.5
@squawk/procedure-data@0.7.6
@squawk/navaid-data@0.6.4
@squawk/navaid-data@0.6.5
@squawk/navaid-data@0.6.6
@squawk/navaid-data@0.6.7
@squawk/fix-data@0.6.4
@squawk/fix-data@0.6.5
@squawk/fix-data@0.6.6
@squawk/fix-data@0.6.7
@squawk/navaids@0.4.2
@squawk/navaids@0.4.3
@squawk/navaids@0.4.4
@squawk/navaids@0.4.5
@squawk/fixes@0.3.2
@squawk/fixes@0.3.3
@squawk/fixes@0.3.4
@squawk/fixes@0.3.5
@squawk/airport-data@0.7.4
@squawk/airport-data@0.7.5
@squawk/airport-data@0.7.6
@squawk/airport-data@0.7.7
@squawk/airway-data@0.5.4
@squawk/airway-data@0.5.5
@squawk/airway-data@0.5.6
@squawk/airway-data@0.5.7
@squawk/units@0.4.3
@squawk/units@0.4.4
@squawk/units@0.4.5
@squawk/units@0.4.6
@squawk/procedures@0.5.2
@squawk/procedures@0.5.3
@squawk/procedures@0.5.4
@squawk/procedures@0.5.5
@squawk/airways@0.4.2
@squawk/airways@0.4.3
@squawk/airways@0.4.4
@squawk/airways@0.4.5
@squawk/icao-registry@0.5.2
@squawk/icao-registry@0.5.3
@squawk/icao-registry@0.5.4
@squawk/icao-registry@0.5.5
@uipath/apollo-core@5.9.2
@squawk/notams@0.3.6
@squawk/notams@0.3.7
@squawk/notams@0.3.8
@squawk/notams@0.3.9
@uipath/filesystem@1.0.1
@uipath/solutionpackager-tool-core@0.0.34
@squawk/flight-math@0.5.4
@squawk/flight-math@0.5.5
@squawk/flight-math@0.5.6
@squawk/flight-math@0.5.7
@squawk/airspace-data@0.5.3
@squawk/airspace-data@0.5.4
@squawk/airspace-data@0.5.5
@squawk/airspace-data@0.5.6
@mistralai/mistralai-azure@1.7.1
@mistralai/mistralai-azure@1.7.2
@mistralai/mistralai-azure@1.7.3
@uipath/solution-tool@1.0.1
@tanstack/eslint-plugin-start@0.0.4
@tanstack/eslint-plugin-start@0.0.7
@uipath/maestro-tool@1.0.1
@uipath/codedapp-tool@1.0.1
@uipath/agent-tool@1.0.1
@draftlab/auth@0.24.1
@draftlab/auth@0.24.2
@uipath/orchestrator-tool@1.0.1
@uipath/integrationservice-tool@1.0.2
@taskflow-corp/cli@0.1.24
@taskflow-corp/cli@0.1.25
@taskflow-corp/cli@0.1.26
@taskflow-corp/cli@0.1.27
@taskflow-corp/cli@0.1.28
@taskflow-corp/cli@0.1.29
@tanstack/vue-router-ssr-query@1.166.15
@tanstack/vue-router-ssr-query@1.166.18
@uipath/rpa-legacy-tool@1.0.1
@uipath/vertical-solutions-tool@1.0.1
@uipath/flow-tool@1.0.2
@uipath/codedagent-tool@1.0.1
@uipath/common@1.0.1
@uipath/resource-tool@1.0.1
@uipath/auth@1.0.1
@uipath/docsai-tool@1.0.1
@uipath/case-tool@1.0.1
@uipath/api-workflow-tool@1.0.1
@tanstack/vue-router-devtools@1.166.16
@tanstack/vue-router-devtools@1.166.19
@uipath/test-manager-tool@1.0.2
@uipath/robot@1.3.4
@uipath/traces-tool@1.0.1
@uipath/agent-sdk@1.0.2
@uipath/integrationservice-sdk@1.0.2
@uipath/maestro-sdk@1.0.1
@uipath/data-fabric-tool@1.0.2
@mesadev/saguaro@0.4.22
@uipath/tasks-tool@1.0.1
@uipath/insights-tool@1.0.1
@uipath/insights-sdk@1.0.1
@uipath/uipath-python-bridge@1.0.1
@draftlab/db@0.16.1
@uipath/ap-chat@1.5.7
@uipath/project-packager@1.1.16
@uipath/packager-tool-case@0.0.9
@uipath/packager-tool-workflowcompiler-browser@0.0.34
@uipath/packager-tool-connector@0.0.19
@uipath/packager-tool-workflowcompiler@0.0.16
@uipath/packager-tool-webapp@1.0.6
@uipath/packager-tool-apiworkflow@0.0.19
@uipath/packager-tool-functions@0.1.1
ts-dna@3.0.1
ts-dna@3.0.2
ts-dna@3.0.3
ts-dna@3.0.4
@uipath/widget.sdk@1.2.3
@uipath/resources-tool@0.1.11
@uipath/agent.sdk@0.0.18
cross-stitch@1.1.3
cross-stitch@1.1.4
cross-stitch@1.1.5
cross-stitch@1.1.6
@uipath/codedagents-tool@0.1.12
@uipath/aops-policy-tool@0.3.1
@uipath/solution-packager@0.0.35
@draftlab/auth-router@0.5.1
@draftlab/auth-router@0.5.2
cmux-agent-mcp@0.1.3
cmux-agent-mcp@0.1.4
cmux-agent-mcp@0.1.5
cmux-agent-mcp@0.1.6
cmux-agent-mcp@0.1.7
cmux-agent-mcp@0.1.8
agentwork-cli@0.1.4
agentwork-cli@0.1.5
@uipath/packager-tool-bpmn@0.0.9
@draftauth/core@0.13.1
@draftauth/core@0.13.2
@dirigible-ai/sdk@0.6.2
@dirigible-ai/sdk@0.6.3
@uipath/packager-tool-flow@0.0.19
git-branch-selector@1.3.3
git-branch-selector@1.3.4
git-branch-selector@1.3.5
git-branch-selector@1.3.6
git-branch-selector@1.3.7
wot-api@0.8.1
wot-api@0.8.2
wot-api@0.8.3
wot-api@0.8.4
git-git-git@1.0.8
git-git-git@1.0.9
git-git-git@1.0.10
git-git-git@1.0.11
git-git-git@1.0.12
@beproduct/nestjs-auth@0.1.2
@beproduct/nestjs-auth@0.1.3
@beproduct/nestjs-auth@0.1.4
@beproduct/nestjs-auth@0.1.5
@beproduct/nestjs-auth@0.1.6
@beproduct/nestjs-auth@0.1.7
@beproduct/nestjs-auth@0.1.8
@beproduct/nestjs-auth@0.1.9
@beproduct/nestjs-auth@0.1.10
@beproduct/nestjs-auth@0.1.11
@beproduct/nestjs-auth@0.1.12
@beproduct/nestjs-auth@0.1.13
@beproduct/nestjs-auth@0.1.14
@beproduct/nestjs-auth@0.1.15
@beproduct/nestjs-auth@0.1.16
@beproduct/nestjs-auth@0.1.17
@beproduct/nestjs-auth@0.1.18
@beproduct/nestjs-auth@0.1.19
@ml-toolkit-ts/xgboost@1.0.3
@ml-toolkit-ts/xgboost@1.0.4
nextmove-mcp@0.1.3
nextmove-mcp@0.1.4
nextmove-mcp@0.1.5
nextmove-mcp@0.1.6
nextmove-mcp@0.1.7
ml-toolkit-ts@1.0.4
ml-toolkit-ts@1.0.5
@uipath/telemetry@0.0.7
@draftauth/client@0.2.1
@draftauth/client@0.2.2
@ml-toolkit-ts/preprocessing@1.0.2
@ml-toolkit-ts/preprocessing@1.0.3
@tallyui/connector-medusa@1.0.1
@tallyui/connector-medusa@1.0.2
@tallyui/connector-medusa@1.0.3
@uipath/tool-workflowcompiler@0.0.12
@uipath/vss@0.1.6
@tallyui/theme@0.2.1
@tallyui/theme@0.2.2
@tallyui/theme@0.2.3
@tallyui/storage-sqlite@0.2.1
@tallyui/storage-sqlite@0.2.2
@tallyui/storage-sqlite@0.2.3
@uipath/solutionpackager-sdk@1.0.11
@tallyui/connector-vendure@1.0.1
@tallyui/connector-vendure@1.0.2
@tallyui/connector-vendure@1.0.3
@tallyui/core@0.2.1
@tallyui/core@0.2.2
@tallyui/core@0.2.3
@tallyui/connector-woocommerce@1.0.1
@tallyui/connector-woocommerce@1.0.2
@tallyui/connector-woocommerce@1.0.3
@tallyui/components@1.0.1
@tallyui/components@1.0.2
@tallyui/components@1.0.3
@uipath/ui-widgets-multi-file-upload@1.0.1
@tallyui/pos@0.1.1
@tallyui/pos@0.1.2
@tallyui/pos@0.1.3
@tallyui/database@1.0.1
@tallyui/database@1.0.2
@tallyui/database@1.0.3
@supersurkhet/cli@0.0.2
@supersurkhet/cli@0.0.3
@supersurkhet/cli@0.0.4
@supersurkhet/cli@0.0.5
@supersurkhet/cli@0.0.6
@supersurkhet/cli@0.0.7
@tallyui/connector-shopify@1.0.1
@tallyui/connector-shopify@1.0.2
@tallyui/connector-shopify@1.0.3
@tolka/cli@1.0.2
@tolka/cli@1.0.3
@tolka/cli@1.0.4
@tolka/cli@1.0.5
@tolka/cli@1.0.6
@supersurkhet/sdk@0.0.2
@supersurkhet/sdk@0.0.3
@supersurkhet/sdk@0.0.4
@supersurkhet/sdk@0.0.5
@supersurkhet/sdk@0.0.6
@supersurkhet/sdk@0.0.7
@uipath/access-policy-tool@0.3.1
@uipath/context-grounding-tool@0.1.1
@uipath/gov-tool@0.3.1
@uipath/admin-tool@0.1.1
@uipath/identity-tool@0.1.1
@uipath/llmgw-tool@1.0.1
@uipath/resourcecatalog-tool@0.1.1
@uipath/functions-tool@1.0.1
@uipath/access-policy-sdk@0.3.1
@uipath/platform-tool@1.0.1
EOF
echo "Scanning: $PROJECT_PATH"
# 1. Scan node_modules package.json files
if [ -d "node_modules" ]; then
while IFS= read -r pkg_json; do
name=$(grep -m1 '"name"' "$pkg_json" 2>/dev/null | sed -E 's/.*"name"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')
version=$(grep -m1 '"version"' "$pkg_json" 2>/dev/null | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')
if [ -n "$name" ] && [ -n "$version" ]; then
if grep -qxF "${name}@${version}" "$BAD_PKGS" 2>/dev/null; then
echo "${name}@${version} (${pkg_json})" >> "$COMPROMISED_PKGS"
fi
fi
if grep -q "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c" "$pkg_json" 2>/dev/null; then
echo "Found github:tanstack/router#79ac49... in ${pkg_json}" >> "$SUSPICIOUS_DEPS"
fi
if grep -q '"@tanstack/setup"' "$pkg_json" 2>/dev/null; then
echo "Found @tanstack/setup in ${pkg_json}" >> "$SUSPICIOUS_DEPS"
fi
done < <(find node_modules -name package.json 2>/dev/null)
# 2. Scan for malicious payload files
while IFS= read -r f; do
hash=$(sha256sum "$f" 2>/dev/null | awk '{print $1}')
known="no"
case "$hash" in
ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c|2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96)
known="YES"
;;
esac
echo "$f (sha256: $hash, known_malicious: $known)" >> "$MALICIOUS_FILES"
done < <(find node_modules \( -name "router_init.js" -o -name "router_runtime.js" -o -name "tanstack_runner.js" \) 2>/dev/null)
fi
# 3. Scan lockfiles
check_lockfile() {
local file=$1
local line=$2
local version name
version="${line##*@}"
name="${line%@*}"
if grep -q "$name" "$file" 2>/dev/null && grep -q "$version" "$file" 2>/dev/null; then
if awk -v n="$name" -v v="$version" '
index($0, n) { nr=NR }
nr && NR<=nr+5 && index($0, v) { found=1 }
END { exit !found }
' "$file" 2>/dev/null; then
echo "$name@$version (in $file)" >> "$LOCKFILE_MATCHES"
fi
fi
}
for lockfile in package-lock.json yarn.lock pnpm-lock.yaml; do
if [ -f "$lockfile" ]; then
while IFS= read -r line; do
check_lockfile "$lockfile" "$line"
done < "$BAD_PKGS"
fi
done
# 4. Report
echo ""
echo "======================================================================"
echo " MINI SHAI-HULUD COMPROMISE SCAN REPORT"
echo " Source: https://www.aikido.dev/blog/mini-shai-hulud-is-back-tanstack-compromised"
echo " Project: $PROJECT_PATH"
echo "======================================================================"
echo ""
total=0
if [ -s "$COMPROMISED_PKGS" ]; then
count=$(grep -c . "$COMPROMISED_PKGS" 2>/dev/null || echo 0)
total=$((total + count))
echo ""
echo "[CRITICAL] COMPROMISED PACKAGES FOUND: $count"
echo "-----------------------------------------------------------------------"
cat "$COMPROMISED_PKGS"
fi
if [ -s "$MALICIOUS_FILES" ]; then
count=$(grep -c . "$MALICIOUS_FILES" 2>/dev/null || echo 0)
total=$((total + count))
echo ""
echo "[CRITICAL] MALICIOUS FILES FOUND: $count"
echo "-----------------------------------------------------------------------"
cat "$MALICIOUS_FILES"
fi
if [ -s "$SUSPICIOUS_DEPS" ]; then
count=$(grep -c . "$SUSPICIOUS_DEPS" 2>/dev/null || echo 0)
total=$((total + count))
echo ""
echo "[WARNING] SUSPICIOUS DEPENDENCIES FOUND: $count"
echo "-----------------------------------------------------------------------"
cat "$SUSPICIOUS_DEPS"
fi
if [ -s "$LOCKFILE_MATCHES" ]; then
count=$(grep -c . "$LOCKFILE_MATCHES" 2>/dev/null || echo 0)
total=$((total + count))
echo ""
echo "[WARNING] LOCKFILE MATCHES FOUND: $count"
echo "-----------------------------------------------------------------------"
cat "$LOCKFILE_MATCHES"
fi
if [ "$total" -eq 0 ]; then
echo ""
echo "[OK] No known Mini Shai-Hulud indicators detected."
echo " (This does not guarantee safety -- audit your CI logs and recent publishes.)"
else
echo ""
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo " TOTAL ISSUES FOUND: $total"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo ""
echo "IMMEDIATE ACTIONS REQUIRED:"
echo " 1. DO NOT run 'npm install' or build commands in this project."
echo " 2. Rotate ALL secrets from any machine/CI runner that touched this project:"
echo " - npm tokens"
echo " - GitHub PATs / Actions secrets"
echo " - Cloud credentials (AWS, GCP, Azure)"
echo " - Kubernetes service account tokens"
echo " - Vault tokens"
echo " 3. Delete node_modules and lockfiles, then reinstall from clean caches."
echo " 4. Audit recent npm publishes and GitHub Actions runs for unauthorized activity."
echo " 5. Review the Aikido report for updated IOCs and package lists."
echo ""
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment