cd /news/ai-safety/mini-shai-hulud-tanstack-mistral-ai-… · home topics ai-safety article
[ARTICLE · art-23693] src=gist.github.com pub= topic=ai-safety verified=true sentiment=↓ negative

Mini Shai-Hulud / TanStack + Mistral AI supply-chain audit script

A developer has released an open-source supply-chain audit script, "Mini Shai-Hulud," designed to detect the TanStack Router and Mistral AI supply-chain attacks. The bash script checks for specific SHA hashes, malicious commits, and known command-and-control infrastructure associated with the incidents. It scans project directories and lockfiles for indicators of compromise, including trojanized tarballs and persistence mechanisms.

read29 min publishedMay 12, 2026

| #!/usr/bin/env bash | | | # | | | # Mini Shai-Hulud / TanStack + Mistral AI supply-chain audit script | | | # | | | # chmod +x tanstack_mistral_audit_public.sh | | | # ./tanstack_mistral_audit_public.sh | | | # sudo ./tanstack_mistral_audit_public.sh | | | # ./tanstack_mistral_audit_public.sh /path/to/project /tmp | | | set -uo pipefail | | | RED='' | | | GREEN='' | | | YELLOW='' | | | NC='' | |

| if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then | |
| RED=$'\033[0;31m' | |
| GREEN=$'\033[0;32m' | |
| YELLOW=$'\033[1;33m' | |
| NC=$'\033[0m' | |

| fi | | | SCRIPT_VERSION="2026-05-12-public" | | | ROUTER_INIT_SHA="ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c" | | | TANSTACK_RUNNER_SHA="2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96" | | | TANSTACK_SETUP_PACKAGE_SHA="7c12d8614c624c70d6dd6fc2ee289332474abaa38f70ebe2cdef064923ca3a9b" | | | SETUP_MJS_SHA="2258284d65f63829bd67eaba01ef6f1ada2f593f9bbe41678b2df360bd90d3df" | | | TANSTACK_TROJANIZED_TARBALL_SHA="1e8538c6e0563d50da0f2e097e979ebd5294ce1defe01d0b9fe361ba3bed1898" | | | MALICIOUS_COMMIT="79ac49eedf774dd4b0cfa308722bc463cfe5885c" | | | MALICIOUS_SETUP_SPEC="github:tanstack/router#${MALICIOUS_COMMIT}" | | | SESSION_RECIPIENT_ID="05f9e609d79eed391015e11380dee4b5c9ead0b6e2e7f0134e6e51767a87323026" | | | PYPI_MISTRAL_C2="83.142.209.194" | | | PYPI_MISTRAL_ENV_MARKER="MISTRAL_INIT" | | | PYPI_PAYLOAD_DOMAIN="git-tanstack.com" | | | PYPI_PAYLOAD_URL_PATH="tmp/transformers.pyz" | | | PYPI_SECOND_STAGE="transformers.pyz" | | | PYPI_SECOND_STAGE_ABS="/tmp/transformers.pyz" | | | PYPI_PERSISTENCE_SCRIPT="pgmonitor.py" | | | PYPI_PERSISTENCE_SERVICE="pgsql-monitor.service" | | | GUARDRAILS_AI_0101_SDIST_SHA="8491b17dc16f31c27f290b3b1e0f2e8866cc775828590e90376ecfb0cc1f8d9c" | | | GUARDRAILS_AI_0101_WHEEL_SHA="b76c800a685c0376a668170b000ba1e5a5ac7daeb714a6af97eac2d31d9a8dbc" | | | MISTRALAI_246_WHEEL_SHA="6dbaa43bf2f3c0d3cddbca74967e952da563fb974c1ef9d4ecbb2e58e41fe81b" | | | MISTRALAI_246_STAGE1_INIT_SHA="2a314ea8be337e1ca9ec833ed13ed854d9fd38bce0a519cf288f3bec8d9e6f30" | | | MISTRALAI_246_TRANSFORMERS_PYZ_SHA="eab7964658dd6ad28cb581d979837cfbf4690c582e0c507e965060defbb89d1b" | | | MISTRALAI_246_STAGE2_MAIN_SHA="59811e589b0caa202e63a07c61129d58443fe8911545fdb3ed9264f8628d68e5" | | | MISTRALAI_246_STAGE2_AGGREGATE_SHA="eeee34f2db5cb3eb5e5877c93e2250d44128c470d24fad38885bbfdab452de09" | | | MISTRALAI_246_STAGE2_CONFIG_SHA="714152c0489c3d8d9196305efa12a6850e5d460ab62ff3be91caf3fb852ec793" | | | MISTRALAI_246_STAGE2_ENTRYPOINT_SHA="e9d0fefa8efc50e4fa9a84375780bef9590dfd60968757a35158ba0d45e265b1" | | | MISTRALAI_246_STAGE2_ROULETTE_SHA="5774ad8f2594f6f1c34cdfb2511dc4728db7b5f4089765600d6c74a353de69a3" | | | MISTRALAI_246_STAGE2_COLLECTORS_AWS_SHA="03cdeb175f6f3d79aeca171841f83d10fff83143b2bc61a22c15f1ccfe484f27" | | | MISTRALAI_246_STAGE2_COLLECTORS_AZURE_SHA="3e0f0fbf089adc0255775cb65b2e8dfc18028bb288376080d7a90a2448b00e92" | | | MISTRALAI_246_STAGE2_COLLECTORS_FILESYSTEM_SHA="50d88c81cac859cb0f446a30229b64336ef4f682a1ed12e1f4cfa03758d57042" | | | MISTRALAI_246_STAGE2_COLLECTORS_GCP_SHA="4c37f2239888b689d67a193bbd7864d33641c9343574412470b4f882aefbff5c" | | | MISTRALAI_246_STAGE2_COLLECTORS_KUBERNETES_SHA="ed81603bb88d8060deb46b474a515d49bb71ca0832a3f6d854b4b886bff25842" | | | MISTRALAI_246_STAGE2_COLLECTORS_PASSWORDS_SHA="630333cc3950387605ad09a528506053e4ff36cee08547b8424958d742a5eac7" | | | MISTRALAI_246_STAGE2_COLLECTORS_VAULT_SHA="0eb70f94b82aa24ae8f69d6644f17ca1173b1318a0d30af142d8f76a5175aa49" | | | MISTRALAI_246_STAGE2_UTILITIES_AWS_SIGNER_SHA="3b48fb6375ca66dba4b38c001a635b53a4e9ebee233a4ff3ac6352674f4ddc38" | | | MISTRALAI_246_STAGE2_UTILITIES_CRYPTO_SHA="831d54a730b2a141ed97ce7a892cec9066c29c9f4094ad6d2ba3e92af97edb51" | |

| INCLUDE_LOCKFILE_SCAN="${INCLUDE_LOCKFILE_SCAN:-true}" | |
| EXIT_ON_MEDIUM="${EXIT_ON_MEDIUM:-false}" | |
| PRINT_FINDING_LIMIT="${PRINT_FINDING_LIMIT:-200}" | |
| FD_THREADS="${FD_THREADS:-1}" | |
| SCAN_ROOTS=() | |

| FILES_SCANNED=0 | | | LOCKFILES_SCANNED=0 | | | FILE_FINDER='' | | | if command -v fdfind >/dev/null 2>&1; then | | | FILE_FINDER='fdfind' | | | elif command -v fd >/dev/null 2>&1; then | | | FILE_FINDER='fd' | | | fi | | | ISSUES_FILE="$(mktemp "${TMPDIR:-/tmp}/tanstack_mistral_audit.XXXXXX")" || exit 2 | | | trap 'rm -f "$ISSUES_FILE"' EXIT | |

| sanitize_field() { | |
| printf '%s' "${1:-}" | tr '\t\n\r' ' ' | cut -c 1-1200 | |

| } | |

| print_header() { | |
| printf '\n%s=== %s ===%s\n' "$YELLOW" "$1" "$NC" | |

| } | |

| print_clean() { | |
| printf '%s[+] CLEAN:%s %s\n' "$GREEN" "$NC" "$1" | |

| } | |

| print_warning() { | |
| printf '%s[?] WARNING:%s %s\n' "$YELLOW" "$NC" "$1" | |

| } | | | add_issue() { | | | printf '%s\t%s\t%s\t%s\n' \ | |

| "$(sanitize_field "$1")" \ | |
| "$(sanitize_field "$2")" \ | |
| "$(sanitize_field "$3")" \ | |
| "$(sanitize_field "$4")" >> "$ISSUES_FILE" | |

| } | | | issue_count() { | | | wc -l < "$ISSUES_FILE" | tr -d ' ' | | | } | | | count_severity() { | | | local severity="$1" | | | awk -F '\t' -v s="$severity" '$1 == s { c++ } END { print c + 0 }' "$ISSUES_FILE" | | | } | |

| actionable_count() { | |
| awk -F '\t' '$1 == "CRITICAL" || $1 == "HIGH" { c++ } END { print c + 0 }' "$ISSUES_FILE" | |

| } | | | medium_count() { | | | count_severity "MEDIUM" | | | } | | | path_is_under() { | | | local child="$1" | | | local parent="$2" | |

| [[ "$child" == "$parent" ]] && return 0 | |
| if [[ "$parent" == "/" ]]; then | |
| [[ "$child" == /* ]] | |

| return | | | fi | | | [[ "$child" == "$parent"/* ]] | | | } | | | add_scan_root() { | | | local candidate="$1" | | | local resolved existing | |

| local kept=() | |
| [[ -d "$candidate" ]] || { | |

| print_warning "Skipping missing directory: $candidate" | | | return | | | } | | | resolved="$(cd "$candidate" 2>/dev/null && pwd -P)" || { | | | print_warning "Skipping unreadable directory: $candidate" | | | return | | | } | |

| if [[ "${#SCAN_ROOTS[@]}" -gt 0 ]]; then | |
| for existing in "${SCAN_ROOTS[@]}"; do | |

| if path_is_under "$resolved" "$existing"; then | | | return | | | fi | | | if ! path_is_under "$existing" "$resolved"; then | | | kept+=("$existing") | | | fi | | | done | | | fi | |

| if [[ "${#kept[@]}" -gt 0 ]]; then | |
| SCAN_ROOTS=("${kept[@]}" "$resolved") | |

| else | | | SCAN_ROOTS=("$resolved") | | | fi | | | } | |

| add_scan_root_if_exists() { | |
| [[ -d "$1" ]] && add_scan_root "$1" | |

| } | | | add_global_package_roots() { | | | local path | | | for path in \ | | | /usr/local/lib/node_modules \ | | | /usr/lib/node_modules \ | | | /opt/homebrew/lib/node_modules \ | | | /Library/Python//site-packages \ | | | /opt/homebrew/lib/python/site-packages \ | | | /usr/local/lib/python*/site-packages \ | | | /usr/local/lib/python*/dist-packages \ | | | /usr/lib/python*/site-packages \ | | | /usr/lib/python*/dist-packages \ | | | /opt//venv/lib/python/site-packages \ | | | /opt//.venv/lib/python/site-packages \ | | | /srv//venv/lib/python/site-packages \ | | | /srv//.venv/lib/python/site-packages; do | | | add_scan_root_if_exists "$path" | | | done | | | } | | | add_default_scan_roots() { | | | local cwd os uid | |

| cwd="$(pwd -P 2>/dev/null || pwd)" | |
| os="$(uname -s 2>/dev/null || printf unknown)" | |
| uid="$(id -u 2>/dev/null || printf 1)" | |
| if [[ "$uid" == "0" ]]; then | |
| if [[ "$os" == "Darwin" ]]; then | |

| add_scan_root_if_exists /Users | | | add_scan_root_if_exists /var/root | | | add_scan_root_if_exists /usr/local/lib/node_modules | | | add_scan_root_if_exists /opt/homebrew/lib/node_modules | | | else | | | add_scan_root_if_exists /home | | | add_scan_root_if_exists /root | | | fi | | | [[ -n "${HOME:-}" && "$HOME" != "/" ]] && add_scan_root_if_exists "$HOME" | | | else | | | [[ -n "${HOME:-}" && "$HOME" != "/" ]] && add_scan_root_if_exists "$HOME" | | | fi | | | case "$cwd" in | | | /|/private|/System|/Library|/Applications|/usr|/usr/local|/opt|/opt/homebrew) ;; | | | *) add_scan_root_if_exists "$cwd" ;; | | | esac | | | add_scan_root_if_exists /tmp | | | add_scan_root_if_exists /var/tmp | | | add_scan_root_if_exists /private/tmp | | | add_scan_root_if_exists /private/var/tmp | | | add_global_package_roots | | | } | |

| hash_file() { | |
| if command -v sha256sum >/dev/null 2>&1; then | |
| sha256sum "$1" 2>/dev/null | awk '{print $1}' | |
| elif command -v shasum >/dev/null 2>&1; then | |
| shasum -a 256 "$1" 2>/dev/null | awk '{print $1}' | |
| elif command -v openssl >/dev/null 2>&1; then | |
| openssl dgst -sha256 "$1" 2>/dev/null | awk '{print $NF}' | |

| else | | | printf 'sha256-unavailable' | | | fi | | | } | |

| file_has() { | |
| grep -Fq -- "$2" "$1" 2>/dev/null | |

| } | |

| file_has_regex() { | |
| grep -Eq -- "$2" "$1" 2>/dev/null | |

| } | | | json_get_string() { | | | local file="$1" | | | local key="$2" | | | sed -nE "s/."${key}"[[:space:]]:[[:space:]]"([^"])".*/\1/p" "$file" 2>/dev/null | head -n 1 | | | } | | | file_has_pkg_version_nearby() { | | | local file="$1" | | | local package_ere="$2" | | | local version_ere="$3" | |

| awk -v pkg="$package_ere" -v ver="$version_ere" ' | |
| BEGIN { found = 0 } | |

| $0 ~ pkg { | |

| if ($0 ~ ver) { found = 1; exit } | |
| for (i = 0; i < 18 && (getline line) > 0; i++) { | |
| if (line ~ ver) { found = 1; exit } | |
| if (line ~ pkg && line ~ ver) { found = 1; exit } | |

| } | | | } | | | END { exit(found ? 0 : 1) } | | | ' "$file" 2>/dev/null | | | } | | | file_has_any_malware_marker() { | | | local file="$1" | | | [[ -f "$file" ]] || return 1 | | | file_has "$file" "filev2.getsession.org" || | | | file_has "$file" "api.masscan.cloud" || | | | file_has "$file" "git-tanstack.com" || | | | file_has "$file" "seed1.getsession.org" || | | | file_has "$file" "seed2.getsession.org" || | | | file_has "$file" "seed3.getsession.org" || | | | file_has "$file" "$SESSION_RECIPIENT_ID" || | | | file_has "$file" "IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner" || | | | file_has "$file" "svksjrhjkcejg" || | | | file_has "$file" "EveryBoiWeBuildIsAWormyBoi" || | | | file_has "$file" "A Mini Shai-Hulud has Appeared" || | | | file_has "$file" "Shai-Hulud: Here We Go Again" || | | | file_has "$file" "PUSH UR T3MPRR" || | | | file_has "$file" "bun run tanstack_runner.js" || | | | file_has "$file" "$MALICIOUS_SETUP_SPEC" || | | | { file_has "$file" "@tanstack/setup" && file_has "$file" "$MALICIOUS_COMMIT"; } | | | } | | | pypi__is_malicious() { | | | local file="$1" | | | [[ -f "$file" ]] || return 1 | | | { file_has "$file" "$PYPI_MISTRAL_ENV_MARKER" && \ | | | { file_has "$file" "$PYPI_MISTRAL_C2" || file_has "$file" "$PYPI_SECOND_STAGE" || file_has "$file" "$PYPI_PAYLOAD_DOMAIN"; }; } || | | | { file_has "$file" "$PYPI_MISTRAL_C2" && file_has "$file" "$PYPI_SECOND_STAGE"; } || | | | { file_has "$file" "$PYPI_PAYLOAD_DOMAIN" && file_has "$file" "$PYPI_SECOND_STAGE"; } || | | | { file_has "$file" "$PYPI_SECOND_STAGE_ABS" && \ | | | { file_has "$file" "subprocess" || file_has "$file" "Popen" || file_has "$file" "curl" || file_has "$file" "urlopen"; }; } | | | } | | | pypi_payload_is_malicious() { | | | local file="$1" | | | [[ -f "$file" ]] || return 1 | | | { file_has "$file" "$PYPI_MISTRAL_ENV_MARKER" && \ | | | { file_has "$file" "$PYPI_MISTRAL_C2" || file_has "$file" "$PYPI_SECOND_STAGE" || file_has "$file" "$PYPI_PAYLOAD_DOMAIN"; }; } || | | | { file_has "$file" "$PYPI_MISTRAL_C2" && \ | | | { file_has "$file" "$PYPI_SECOND_STAGE" || file_has "$file" "$PYPI_PERSISTENCE_SCRIPT" || file_has "$file" "$PYPI_PERSISTENCE_SERVICE" || file_has "$file" "PUSH UR T3MPRR"; }; } || | | | { file_has "$file" "$PYPI_PAYLOAD_DOMAIN" && file_has "$file" "$PYPI_SECOND_STAGE"; } || | | | { file_has "$file" "$PYPI_SECOND_STAGE" && file_has "$file" "$PYPI_PERSISTENCE_SCRIPT" && file_has "$file" "$PYPI_PERSISTENCE_SERVICE"; } || | | | { file_has "$file" "FIRESCALE" && file_has "$file" "$PYPI_MISTRAL_C2"; } || | | | { file_has "$file" "PUSH UR T3MPRR" && file_has "$file" "RunForCover.mp3"; } | | | } | | | pypi_service_points_to_monitor() { | | | local file="$1" | | | [[ -f "$file" ]] || return 1 | | | file_has "$file" "$PYPI_PERSISTENCE_SCRIPT" && \ | | | { file_has "$file" "$PYPI_PERSISTENCE_SERVICE" || file_has "$file" "ExecStart" || file_has "$file" "systemd"; } | | | } | | | pypi_metadata_compromised_package() { | | | local file="$1" | | | [[ -f "$file" ]] || return 1 | | | if file_has "$file" "Name: mistralai" && file_has "$file" "Version: 2.4.6"; then | | | printf 'mistralai==2.4.6' | | | return 0 | | | fi | | | if file_has "$file" "Name: guardrails-ai" && file_has "$file" "Version: 0.10.1"; then | | | printf 'guardrails-ai==0.10.1' | | | return 0 | | | fi | | | return 1 | | | } | | | node_metadata_compromised_package() { | | | local file="$1" | | | local name version | |

| [[ -f "$file" ]] || return 1 | |
| name="$(json_get_string "$file" name)" | |
| version="$(json_get_string "$file" version)" | |
| case "${name}:${version}" in | |

| '@mistralai/mistralai:2.2.2'|'@mistralai/mistralai:2.2.3'|'@mistralai/mistralai:2.2.4'|'@mistralai/mistralai-azure:1.7.1'|'@mistralai/mistralai-azure:1.7.2'|'@mistralai/mistralai-azure:1.7.3'|'@mistralai/mistralai-gcp:1.7.1'|'@mistralai/mistralai-gcp:1.7.2'|'@mistralai/mistralai-gcp:1.7.3') | | | printf '%s@%s' "$name" "$version" | | | return 0 | | | ;; | | | esac | | | return 1 | | | } | | | exposure_marker_for_depfile() { | | | local file="$1" | |

| [[ -f "$file" ]] || return 1 | |
| if file_has_pkg_version_nearby "$file" '@mistralai/mistralai-azure([^A-Za-z0-9_.-]|$)' '1[.]7[.][123]'; then | |

| printf '@mistralai/mistralai-azure affected version marker' | | | return 0 | | | fi | | | if file_has_pkg_version_nearby "$file" '@mistralai/mistralai-gcp([^A-Za-z0-9_.-]|$)' '1[.]7[.][123]'; then | | | printf '@mistralai/mistralai-gcp affected version marker' | | | return 0 | | | fi | | | if file_has_pkg_version_nearby "$file" '@mistralai/mistralai([^A-Za-z0-9_.-]|$)' '2[.]2[.][234]'; then | | | printf '@mistralai/mistralai affected version marker' | | | return 0 | | | fi | |

| if file_has_pkg_version_nearby "$file" '(^|[^A-Za-z0-9_./@-])mistralai([^A-Za-z0-9_./-]|$)' '2[.]4[.]6' || \ | |
| file_has_regex "$file" '(^|[^A-Za-z0-9_./@-])mistralai([^A-Za-z0-9_./-]|[[:space:]])+([^#\r\n]*)2[.]4[.]6'; then | |
| printf 'mistralai==2.4.6 marker' | |

| return 0 | | | fi | |

| if file_has_pkg_version_nearby "$file" '(^|[^A-Za-z0-9_.-])guardrails-ai([^A-Za-z0-9_.-]|$)' '0[.]10[.]1' || \ | |
| file_has_pkg_version_nearby "$file" '(^|[^A-Za-z0-9_.-])guardrails_ai([^A-Za-z0-9_.-]|$)' '0[.]10[.]1' || \ | |
| file_has_regex "$file" '(^|[^A-Za-z0-9_.-])guardrails[-_]ai([^A-Za-z0-9_.-]|[[:space:]])+([^#\r\n]*)0[.]10[.]1'; then | |
| printf 'guardrails-ai==0.10.1 marker' | |

| return 0 | | | fi | | | return 1 | | | } | | | file_hash_is_known_malicious() { | | | local file="$1" | | | local digest | | | digest="$(hash_file "$file")" | | | case "$digest" in | | | "$ROUTER_INIT_SHA"|"$TANSTACK_RUNNER_SHA"|"$TANSTACK_SETUP_PACKAGE_SHA"|"$SETUP_MJS_SHA"|"$TANSTACK_TROJANIZED_TARBALL_SHA"|"$GUARDRAILS_AI_0101_SDIST_SHA"|"$GUARDRAILS_AI_0101_WHEEL_SHA"|"$MISTRALAI_246_WHEEL_SHA"|"$MISTRALAI_246_STAGE1_INIT_SHA"|"$MISTRALAI_246_TRANSFORMERS_PYZ_SHA"|"$MISTRALAI_246_STAGE2_MAIN_SHA"|"$MISTRALAI_246_STAGE2_AGGREGATE_SHA"|"$MISTRALAI_246_STAGE2_CONFIG_SHA"|"$MISTRALAI_246_STAGE2_ENTRYPOINT_SHA"|"$MISTRALAI_246_STAGE2_ROULETTE_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_AWS_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_AZURE_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_FILESYSTEM_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_GCP_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_KUBERNETES_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_PASSWORDS_SHA"|"$MISTRALAI_246_STAGE2_COLLECTORS_VAULT_SHA"|"$MISTRALAI_246_STAGE2_UTILITIES_AWS_SIGNER_SHA"|"$MISTRALAI_246_STAGE2_UTILITIES_CRYPTO_SHA") | | | printf '%s' "$digest" | | | return 0 | | | ;; | | | esac | | | return 1 | | | } | | | installed_package_has_malicious_setup() { | | | local package_json="$1" | | | [[ "$package_json" == /node_modules//package.json ]] || return 1 | | | file_has "$package_json" '"@tanstack/setup"' && file_has "$package_json" "$MALICIOUS_SETUP_SPEC" | | | } | | | lockfile_has_malicious_setup() { | | | local lockfile="$1" | | | file_has "$lockfile" "@tanstack/setup" && file_has "$lockfile" "$MALICIOUS_COMMIT" | | | } | | | persistence_script_is_malicious() { | | | local file="$1" | | | local digest | |

| [[ -f "$file" ]] || return 1 | |
| if digest="$(file_hash_is_known_malicious "$file")"; then | |

| return 0 | | | fi | | | file_has_any_malware_marker "$file" | | | } | | | find_candidate_files() { | | | local root="$1" | |

| if [[ -n "$FILE_FINDER" ]]; then | |
| "$FILE_FINDER" -0 -j "$FD_THREADS" -H -I -t f \ | |

| -E .git \ | | | -E .hg \ | | | -E .svn \ | | | -E target \ | | | -E .cache \ | | | -E node_modules/.cache \ | | | -E .pnpm-store \ | | | -E .yarn/cache \ | | | -E .Trash \ | | | -E Library/Caches \ | | | -E Library/Developer/Xcode/DerivedData \ | | | -p '(^|/)(router_init.js|tanstack_runner.js|router_runtime.js|node_modules/.*/package.json|mistralai/client/init.py|guardrails/init.py|mistralai-2.4.6.dist-info/METADATA|guardrails[_-]ai-0.10.1.dist-info/METADATA|mistralai-2.4.6(-py3-none-any.whl|.tar.gz)|guardrails_ai-0.10.1(-py3-none-any.whl|.tar.gz)|transformers.pyz|pgmonitor.py|pgsql-monitor.service|main.py|aggregate.py|config.py|entrypoint.py|roulette.py|collectors/(aws|azure|filesystem|gcp|kubernetes|passwords|vault).py|utilities/(aws_signer|crypto).py|.claude/(settings.json|router_runtime.js|setup.mjs)|.vscode/(tasks.json|setup.mjs)|gh-token-monitor.service|com.user.gh-token-monitor.plist|gh-token-monitor.sh|.config/gh-token-monitor/token|.github/workflows/codeql_analysis.ya?ml)$' \ | | | "$root" 2>/dev/null | | | return | | | fi | | | find "$root" \ | | | ( \ | |

| -path '*/.git' -o \ | |
| -path '*/.hg' -o \ | |
| -path '*/.svn' -o \ | |
| -path '*/target' -o \ | |
| -path '*/.cache' -o \ | |

| -path '*/node_modules/.cache' -o \ | |

| -path '*/.pnpm-store' -o \ | |
| -path '*/.yarn/cache' -o \ | |
| -path '*/.Trash' -o \ | |
| -path '*/Library/Caches' -o \ | |

| -path '*/Library/Developer/Xcode/DerivedData' \ | |

| \) -prune -o \ | |
| -type f \( \ | |
| -name 'router_init.js' -o \ | |
| -name 'tanstack_runner.js' -o \ | |
| -name 'router_runtime.js' -o \ | |

| -path '/node_modules//package.json' -o \ | | | -path '/mistralai/client/init.py' -o \ | | | -path '/guardrails/init.py' -o \ | |

| -path '*/mistralai-2.4.6.dist-info/METADATA' -o \ | |
| -path '*/guardrails_ai-0.10.1.dist-info/METADATA' -o \ | |
| -path '*/guardrails-ai-0.10.1.dist-info/METADATA' -o \ | |
| -name 'mistralai-2.4.6-py3-none-any.whl' -o \ | |
| -name 'mistralai-2.4.6.tar.gz' -o \ | |
| -name 'guardrails_ai-0.10.1-py3-none-any.whl' -o \ | |
| -name 'guardrails_ai-0.10.1.tar.gz' -o \ | |
| -name 'transformers.pyz' -o \ | |
| -name 'pgmonitor.py' -o \ | |
| -name 'pgsql-monitor.service' -o \ | |
| -name '__main__.py' -o \ | |
| -name 'aggregate.py' -o \ | |
| -name 'config.py' -o \ | |
| -name 'entrypoint.py' -o \ | |
| -name 'roulette.py' -o \ | |
| -path '*/collectors/aws.py' -o \ | |

| -path '/collectors/azure.py' -o \ | | | -path '/collectors/filesystem.py' -o \ | | | -path '/collectors/gcp.py' -o \ | | | -path '/collectors/kubernetes.py' -o \ | | | -path '/collectors/passwords.py' -o \ | | | -path '/collectors/vault.py' -o \ | | | -path '/utilities/aws_signer.py' -o \ | | | -path '/utilities/crypto.py' -o \ | | | -path '/.claude/settings.json' -o \ | | | -path '/.claude/router_runtime.js' -o \ | |

| -path '*/.claude/setup.mjs' -o \ | |
| -path '*/.vscode/tasks.json' -o \ | |
| -path '*/.vscode/setup.mjs' -o \ | |
| -name 'gh-token-monitor.service' -o \ | |
| -name 'com.user.gh-token-monitor.plist' -o \ | |
| -name 'gh-token-monitor.sh' -o \ | |
| -path '*/.config/gh-token-monitor/token' -o \ | |

| -path '/.github/workflows/codeql_analysis.yml' -o \ | | | -path '/.github/workflows/codeql_analysis.yaml' \ | | | ) -print0 2>/dev/null | | | } | | | find_exposure_files() { | | | local root="$1" | |

| if [[ -n "$FILE_FINDER" ]]; then | |
| "$FILE_FINDER" -0 -j "$FD_THREADS" -H -I -t f \ | |

| -E .git \ | | | -E .hg \ | | | -E .svn \ | | | -E target \ | | | -E .cache \ | | | -E node_modules \ | | | -E .pnpm-store \ | | | -E .yarn/cache \ | | | -E .Trash \ | | | -E Library/Caches \ | | | -E Library/Developer/Xcode/DerivedData \ | | | -p '(^|/)(package.json|package-lock.json|npm-shrinkwrap.json|pnpm-lock.yaml|yarn.lock|requirements.*.txt|pyproject.toml|uv.lock|poetry.lock|Pipfile|Pipfile.lock|pdm.lock|environment.ya?ml)$' \ | | | "$root" 2>/dev/null | | | return | | | fi | | | find "$root" \ | | | ( \ | |

| -path '*/.git' -o \ | |
| -path '*/.hg' -o \ | |
| -path '*/.svn' -o \ | |
| -path '*/target' -o \ | |
| -path '*/.cache' -o \ | |
| -path '*/node_modules' -o \ | |
| -path '*/.pnpm-store' -o \ | |
| -path '*/.yarn/cache' -o \ | |
| -path '*/.Trash' -o \ | |
| -path '*/Library/Caches' -o \ | |

| -path '*/Library/Developer/Xcode/DerivedData' \ | |

| \) -prune -o \ | |
| -type f \( \ | |
| -name 'package.json' -o \ | |
| -name 'package-lock.json' -o \ | |
| -name 'npm-shrinkwrap.json' -o \ | |
| -name 'pnpm-lock.yaml' -o \ | |
| -name 'yarn.lock' -o \ | |
| -name 'requirements*.txt' -o \ | |
| -name 'pyproject.toml' -o \ | |
| -name 'uv.lock' -o \ | |
| -name 'poetry.lock' -o \ | |
| -name 'Pipfile' -o \ | |
| -name 'Pipfile.lock' -o \ | |
| -name 'pdm.lock' -o \ | |
| -name 'environment.yml' -o \ | |

| -name 'environment.yaml' \ | | | ) -print0 2>/dev/null | | | } | | | scan_candidate_files() { | | | print_header "Checking confirmed filesystem indicators" | | | local before root file digest basename project_root setup_file setup_file2 pypi_package npm_package | |

| before="$(issue_count)" | |
| for root in "${SCAN_ROOTS[@]}"; do | |
| while IFS= read -r -d '' file; do | |
| FILES_SCANNED=$((FILES_SCANNED + 1)) | |
| basename="$(basename "$file")" | |

| case "$file" in | | | /router_init.js|/tanstack_runner.js|/router_runtime.js|/.claude/setup.mjs|*/.vscode/setup.mjs) | | | if digest="$(file_hash_is_known_malicious "$file")"; then | | | add_issue "CRITICAL" "known malicious payload hash" "$file" "sha256=$digest" | | | continue | | | fi | | | if file_has_any_malware_marker "$file"; then | | | add_issue "CRITICAL" "malicious payload marker" "$file" "high-confidence Mini Shai-Hulud marker found" | | | continue | | | fi | |

| if [[ "$basename" == "router_init.js" ]]; then | |
| setup_file="$(dirname "$file")/package.json" | |

| if installed_package_has_malicious_setup "$setup_file"; then | | | add_issue "CRITICAL" "infected installed package artifact" "$file" "router_init.js next to exact malicious @tanstack/setup dependency" | | | fi | | | fi | | | ;; | | | /mistralai/client/init.py) | | | if pypi__is_malicious "$file"; then | | | add_issue "CRITICAL" "compromised PyPI mistralai " "$file" "import-time references ${PYPI_MISTRAL_ENV_MARKER}/${PYPI_MISTRAL_C2}/${PYPI_SECOND_STAGE}" | | | fi | | | ;; | | | /guardrails/init.py) | | | if pypi__is_malicious "$file"; then | | | add_issue "CRITICAL" "compromised PyPI guardrails-ai " "$file" "import-time references ${PYPI_PAYLOAD_DOMAIN}/${PYPI_SECOND_STAGE}" | | | fi | | | ;; | | | /main.py|/aggregate.py|/config.py|/entrypoint.py|/roulette.py|/collectors/aws.py|/collectors/azure.py|/collectors/filesystem.py|/collectors/gcp.py|/collectors/kubernetes.py|/collectors/passwords.py|/collectors/vault.py|/utilities/aws_signer.py|/utilities/crypto.py) | | | if digest="$(file_hash_is_known_malicious "$file")"; then | | | add_issue "CRITICAL" "known malicious extracted PyPI payload hash" "$file" "sha256=$digest" | | | fi | |

| ;; | |
| */mistralai-2.4.6.dist-info/METADATA|*/guardrails_ai-0.10.1.dist-info/METADATA|*/guardrails-ai-0.10.1.dist-info/METADATA) | |
| if pypi_package="$(pypi_metadata_compromised_package "$file")"; then | |

| add_issue "HIGH" "installed compromised PyPI package version" "$file" "$pypi_package installed; verify whether it was imported or used on this host" | | | fi | |

| ;; | |
| */mistralai-2.4.6-py3-none-any.whl|*/mistralai-2.4.6.tar.gz|*/guardrails_ai-0.10.1-py3-none-any.whl|*/guardrails_ai-0.10.1.tar.gz) | |
| if digest="$(file_hash_is_known_malicious "$file")"; then | |

| add_issue "HIGH" "known compromised PyPI package archive hash" "$file" "sha256=$digest" | | | fi | | | ;; | | | */transformers.pyz) | | | if digest="$(file_hash_is_known_malicious "$file")"; then | | | add_issue "CRITICAL" "known malicious PyPI second-stage hash" "$file" "sha256=$digest" | | | continue | | | fi | | | if pypi_payload_is_malicious "$file"; then | | | add_issue "CRITICAL" "PyPI second-stage payload" "$file" "Mini Shai-Hulud PyPI payload markers found" | | | fi | | | ;; | | | */pgmonitor.py) | | | if pypi_payload_is_malicious "$file"; then | | | add_issue "CRITICAL" "PyPI persistence payload" "$file" "Mini Shai-Hulud PyPI persistence markers found" | | | fi | |

| ;; | |
| */pgsql-monitor.service) | |

| if pypi_service_points_to_monitor "$file"; then | | | add_issue "CRITICAL" "PyPI systemd persistence artifact" "$file" "pgsql-monitor service points to pgmonitor.py" | | | fi | | | ;; | | | /node_modules//package.json) | | | if installed_package_has_malicious_setup "$file"; then | | | add_issue "CRITICAL" "infected installed package marker" "$file" "exact malicious @tanstack/setup dependency found in node_modules package.json" | | | continue | | | fi | | | if npm_package="$(node_metadata_compromised_package "$file")"; then | | | add_issue "HIGH" "installed compromised npm package version" "$file" "$npm_package installed; treat this install environment as exposed" | | | continue | | | fi | | | case "$file" in | | | /node_modules/@tanstack/setup/package.json|/node_modules/.pnpm/*/node_modules/@tanstack/setup/package.json) | | | if digest="$(file_hash_is_known_malicious "$file")"; then | | | add_issue "CRITICAL" "known malicious @tanstack/setup manifest hash" "$file" "sha256=$digest" | | | fi | | | ;; | | | esac | | | ;; | | | */.claude/settings.json) | | | project_root="$(dirname "$(dirname "$file")")" | | | setup_file="$project_root/.claude/setup.mjs" | | | setup_file2="$project_root/.vscode/setup.mjs" | | | if { file_has "$file" "hooks" || file_has "$file" "SessionStart"; } && \ | | | { file_has "$file" "router_runtime.js" || file_has "$file" "setup.mjs" || file_has "$file" ".vscode/setup.mjs" || file_has "$file" ".claude/setup.mjs"; }; then | | | if persistence_script_is_malicious "$setup_file" || persistence_script_is_malicious "$setup_file2" || file_has_any_malware_marker "$file"; then | | | add_issue "CRITICAL" "Claude Code persistence hook" "$file" "hook references malicious setup/router runtime payload" | | | fi | | | fi | | | ;; | | | */.vscode/tasks.json) | | | project_root="$(dirname "$(dirname "$file")")" | | | setup_file="$project_root/.vscode/setup.mjs" | | | setup_file2="$project_root/.claude/setup.mjs" | | | if { file_has "$file" "folderOpen" || file_has "$file" "runOn" || file_has "$file" "setup.mjs"; } && \ | | | { file_has "$file" "setup.mjs" || file_has "$file" "router_runtime.js" || file_has "$file" ".claude/setup.mjs" || file_has "$file" ".vscode/setup.mjs"; }; then | | | if persistence_script_is_malicious "$setup_file" || persistence_script_is_malicious "$setup_file2" || file_has_any_malware_marker "$file"; then | | | add_issue "CRITICAL" "VS Code persistence task" "$file" "task references malicious setup/router runtime payload" | | | fi | | | fi | |

| ;; | |
| */gh-token-monitor.service|*/com.user.gh-token-monitor.plist) | |

| if file_has "$file" "gh-token-monitor" && \ | | | { file_has "$file" ".config/gh-token-monitor" || file_has "$file" ".local/bin/gh-token-monitor.sh" || file_has "$file" "gh-token-monitor.sh" || file_has "$file" "api.github.com/user"; }; then | | | add_issue "CRITICAL" "service persistence artifact" "$file" "gh-token-monitor service/LaunchAgent points to malware token monitor" | | | fi | |

| ;; | |
| */gh-token-monitor.sh) | |

| if file_has "$file" "GH_TOKEN" && \ | | | { file_has "$file" "api.github.com/user" || file_has "$file" ".config/gh-token-monitor/token" || file_has "$file" "IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner" || file_has "$file" "rm -rf"; }; then | | | add_issue "CRITICAL" "service persistence artifact" "$file" "gh-token-monitor script contains token monitor/wiper markers" | | | fi | |

| ;; | |
| */.config/gh-token-monitor/token) | |
| if [[ -s "$file" ]]; then | |

| add_issue "CRITICAL" "service persistence token store" "$file" "non-empty gh-token-monitor token store" | | | fi | | | ;; | | | /.github/workflows/codeql_analysis.yml|/.github/workflows/codeql_analysis.yaml) | | | if file_has "$file" "toJSON(secrets)" && \ | | | { file_has "$file" "api.masscan.cloud" || file_has "$file" "filev2.getsession.org" || file_has "$file" "format-results" || file_has "$file" "CodeQL Analysis"; }; then | | | add_issue "CRITICAL" "secret-exfiltration workflow" "$file" "workflow serializes GitHub secrets" | | | fi | | | ;; | | | esac | | | done < <(find_candidate_files "$root") | | | done | | | if [[ "$(issue_count)" == "$before" ]]; then | | | print_clean "No confirmed filesystem indicators found." | | | fi | | | } | |

| scan_lockfiles_for_exposure() { | |
| [[ "$INCLUDE_LOCKFILE_SCAN" == "true" ]] || return 0 | |

| print_header "Checking dependency and lockfile exposure markers" | | | local before root file marker | |

| before="$(issue_count)" | |
| for root in "${SCAN_ROOTS[@]}"; do | |
| while IFS= read -r -d '' file; do | |
| LOCKFILES_SCANNED=$((LOCKFILES_SCANNED + 1)) | |

| if lockfile_has_malicious_setup "$file"; then | | | add_issue "MEDIUM" "lockfile exposure marker" "$file" "exact malicious @tanstack/setup commit appears in dependency file; verify whether install scripts ran on this host" | | | continue | | | fi | | | if marker="$(exposure_marker_for_depfile "$file")"; then | | | add_issue "MEDIUM" "dependency exposure marker" "$file" "$marker; verify whether this resolved/installed on this host" | | | fi | | | done < <(find_exposure_files "$root") | | | done | | | if [[ "$(issue_count)" == "$before" ]]; then | | | print_clean "No dependency or lockfile exposure markers found." | | | fi | | | } | | | scan_system_persistence_paths() { | | | print_header "Checking confirmed system persistence paths" | | | local before file | | | before="$(issue_count)" | | | for file in \ | | | /Library/LaunchAgents/com.user.gh-token-monitor.plist \ | | | /Library/LaunchDaemons/com.user.gh-token-monitor.plist \ | | | /var/root/Library/LaunchAgents/com.user.gh-token-monitor.plist \ | | | /etc/systemd/system/gh-token-monitor.service \ | | | /etc/systemd/system/pgsql-monitor.service \ | | | /lib/systemd/system/gh-token-monitor.service \ | | | /lib/systemd/system/pgsql-monitor.service \ | | | /usr/lib/systemd/system/gh-token-monitor.service \ | | | /usr/lib/systemd/system/pgsql-monitor.service; do | |

| if [[ -e "$file" ]] && file_has "$file" "gh-token-monitor" && \ | |
| { file_has "$file" ".config/gh-token-monitor" || file_has "$file" ".local/bin/gh-token-monitor.sh" || file_has "$file" "gh-token-monitor.sh" || file_has "$file" "api.github.com/user"; }; then | |

| add_issue "CRITICAL" "system persistence artifact" "$file" "gh-token-monitor service/LaunchAgent points to malware token monitor" | | | continue | | | fi | | | if [[ -e "$file" ]] && pypi_service_points_to_monitor "$file"; then | | | add_issue "CRITICAL" "PyPI system persistence artifact" "$file" "pgsql-monitor service points to pgmonitor.py" | | | fi | | | done | | | if [[ "$(issue_count)" == "$before" ]]; then | | | print_clean "No confirmed system persistence paths found." | | | fi | | | } | | | scan_processes() { | | | print_header "Checking running process command lines" | | | local before pid cmd | |

| before="$(issue_count)" | |
| while read -r pid cmd; do | |
| [[ -n "$pid" ]] || continue | |
| [[ -n "${cmd:-}" ]] || continue | |
| [[ "$pid" == "$$" ]] && continue | |

| case "$cmd" in | | | tanstack_mistral_audit_public.sh*|tanstack_audit_public.sh|mini-shai-hulud-ioc-scanner) continue ;; | | | find\ |/find\ |fd\ |/fd\ |fdfind\ |/fdfind\ |rg\ |/rg\ |grep\ |/grep\ ) continue ;; | | | ' find '|' fd '|' fdfind '|' rg '|' grep ') continue ;; | | | esac | | | case "$cmd" in | | | 'bun run tanstack_runner.js'|'tanstack_runner.js'|'router_runtime.js'|'filev2.getsession.org'|'api.masscan.cloud'|'git-tanstack.com'|'IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner'|'gh-token-monitor'|'83.142.209.194'|'/tmp/transformers.pyz'|'/private/tmp/transformers.pyz'|'/var/tmp/transformers.pyz'|'/private/var/tmp/transformers.pyz'*) | | | add_issue "HIGH" "running process command-line indicator" "pid=$pid" "$cmd" | | | ;; | | | esac | |

| done < <(ps -axo pid=,command= 2>/dev/null || true) | |
| if [[ "$(issue_count)" == "$before" ]]; then | |

| print_clean "No running process command-line indicators found." | | | fi | | | } | |

| scan_process_environments() { | |
| [[ "$(uname -s 2>/dev/null || printf unknown)" == "Linux" ]] || return 0 | |

| print_header "Checking Linux process environments" | | | local before envfile pid cmd | |

| before="$(issue_count)" | |
| for envfile in /proc/[0-9]*/environ; do | |
| [[ -r "$envfile" ]] || continue | |
| if tr '\0' '\n' < "$envfile" 2>/dev/null | grep -Fq "${PYPI_MISTRAL_ENV_MARKER}=1"; then | |
| pid="${envfile#/proc/}" | |
| pid="${pid%/environ}" | |
| cmd="$(tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | cut -c 1-240)" | |
| add_issue "HIGH" "running process environment indicator" "pid=$pid" "${PYPI_MISTRAL_ENV_MARKER}=1 ${cmd:+cmd=$cmd}" | |

| fi | | | done | | | if [[ "$(issue_count)" == "$before" ]]; then | | | print_clean "No Linux process environment indicators found." | | | fi | | | } | | | scan_network_connections() { | | | print_header "Checking active network indicators" | | | local before output | | | before="$(issue_count)" | | | output='' | |

| if command -v lsof >/dev/null 2>&1; then | |
| output="$(lsof -nP -iTCP -iUDP 2>/dev/null | grep -F "$PYPI_MISTRAL_C2" | head -n 5 || true)" | |
| elif command -v ss >/dev/null 2>&1; then | |
| output="$(ss -tunap 2>/dev/null | grep -F "$PYPI_MISTRAL_C2" | head -n 5 || true)" | |
| elif command -v netstat >/dev/null 2>&1; then | |
| output="$(netstat -anv 2>/dev/null | grep -F "$PYPI_MISTRAL_C2" | head -n 5 || true)" | |

| else | | | print_warning "No supported network inspection tool found (lsof/ss/netstat); skipped active connection check." | | | return 0 | | | fi | | | if [[ -n "$output" ]]; then | | | add_issue "HIGH" "active network indicator" "$PYPI_MISTRAL_C2" "$output" | | | fi | | | if [[ "$(issue_count)" == "$before" ]]; then | | | print_clean "No active network indicators found." | | | fi | | | } | | | print_summary() { | | | local count actionable medium severity category path detail i | |

| count="$(issue_count)" | |
| actionable="$(actionable_count)" | |
| medium="$(medium_count)" | |
| printf '\n%s----------------------------------------%s\n' "$YELLOW" "$NC" | |

| printf 'Files inspected: %s\n' "$FILES_SCANNED" | | | if [[ "$INCLUDE_LOCKFILE_SCAN" == "true" ]]; then | | | printf 'Dependency/lockfiles inspected: %s\n' "$LOCKFILES_SCANNED" | | | fi | | | if [[ "$count" -eq 0 ]]; then | | | printf '%sAUDIT COMPLETE: No issues detected.%s\n' "$GREEN" "$NC" | | | return | | | fi | | | printf '%sAUDIT COMPLETE: %s finding(s) detected (%s actionable, %s medium exposure).%s\n' "$RED" "$count" "$actionable" "$medium" "$NC" | | | printf '\nFindings:\n' | | | i=0 | | | while IFS=$'\t' read -r severity category path detail; do | |

| i=$((i + 1)) | |
| [[ "$i" -le "$PRINT_FINDING_LIMIT" ]] || continue | |
| printf ' [%s] %s: %s -- %s\n' "$severity" "$category" "$path" "$detail" | |

| done < "$ISSUES_FILE" | |

| if [[ "$count" -gt "$PRINT_FINDING_LIMIT" ]]; then | |
| printf ' ... %s more finding(s) suppressed; set PRINT_FINDING_LIMIT to increase.\n' "$((count - PRINT_FINDING_LIMIT))" | |

| fi | | | if [[ "$medium" -gt 0 && "$actionable" -eq 0 ]]; then | | | printf '\nNote: MEDIUM dependency/lockfile findings are exposure evidence, not proof of active persistence or current process execution. Confirm whether install/import scripts ran on this host before treating it as actively infected.\n' | | | fi | | | } | | | usage() { | | | cat <<USAGE | | | Usage: $(basename "$0") [--exposure|--include-lockfiles] [--no-exposure] [DIR ...] | | | Run without arguments to scan likely local locations. Pass one or more directories | | | to scan only those paths. | | | Environment: | | | INCLUDE_LOCKFILE_SCAN=true Scan dependency and lockfiles for affected TanStack/Mistral/PyPI versions. Default: true. | | | EXIT_ON_MEDIUM=true Exit non-zero for MEDIUM exposure-only findings. Default: false. | | | FD_THREADS=1 Threads used by fd/fdfind when available. | | | PRINT_FINDING_LIMIT=200 Max findings printed to stdout. | | | USAGE | | | } | | | main() { | | | local root | | | while [[ "$#" -gt 0 ]]; do | | | case "$1" in | | | --help|-h) | | | usage | | | exit 0 | |

| ;; | |
| --include-lockfiles|--exposure) | |

| INCLUDE_LOCKFILE_SCAN=true | | | shift | |

| ;; | |
| --no-exposure) | |

| INCLUDE_LOCKFILE_SCAN=false | | | shift | |

| ;; | |
| --*) | |

| printf 'Unknown option: %s\n' "$1" >&2 | | | usage >&2 | | | exit 2 | | | ;; | | | *) | | | add_scan_root "$1" | | | shift | | | ;; | | | esac | | | done | |

| [[ "${#SCAN_ROOTS[@]}" -eq 0 ]] && add_default_scan_roots | |
| if [[ "${#SCAN_ROOTS[@]}" -eq 0 ]]; then | |

| printf 'No valid scan roots provided.\n' >&2 | | | exit 2 | | | fi | | | printf '%s----------------------------------------%s\n' "$YELLOW" "$NC" | | | printf '%s Mini Shai-Hulud / TanStack + Mistral AI Audit%s\n' "$YELLOW" "$NC" | | | printf '%s----------------------------------------%s\n' "$YELLOW" "$NC" | | | printf 'Version: %s\n' "$SCRIPT_VERSION" | |

| if [[ -n "$FILE_FINDER" ]]; then | |
| printf 'File search: %s (threads=%s)\n' "$FILE_FINDER" "$FD_THREADS" | |

| else | | | printf 'File search: find\n' | | | fi | | | printf 'Dependency/lockfile exposure scan: %s\n' "$INCLUDE_LOCKFILE_SCAN" | | | printf 'Scan roots:\n' | | | for root in "${SCAN_ROOTS[@]}"; do | | | printf ' - %s\n' "$root" | | | done | | | scan_candidate_files | | | scan_system_persistence_paths | | | scan_processes | | | scan_process_environments | | | scan_network_connections | | | scan_lockfiles_for_exposure | | | print_summary | | | if [[ "$(actionable_count)" -gt 0 ]]; then | | | exit 1 | | | fi | | | if [[ "$EXIT_ON_MEDIUM" == "true" && "$(medium_count)" -gt 0 ]]; then | | | exit 1 | | | fi | | | exit 0 | | | } | | | main "$@" |

── more in #ai-safety 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/mini-shai-hulud-tans…] indexed:0 read:29min 2026-05-12 ·