
TanStack npm サプライチェーン攻撃の兆候(CVE-2026-45321 / GHSA-g7cv-rxg3-hmpx)を検出するシェルスクリプト
TanStack npm サプライチェーン攻撃の兆候を、開発者マシン、リポジトリ、または CI ランナー上で検出します。Bash スクリプト、Docker イメージ、GitHub Action — 同じエンジンを 3 つのエントリポイントから利用できます。
CVE-2026-45321 / GHSA-g7cv-rxg3-hmpx
2026年5月11日、攻撃者は GitHub Actions のキャッシュポイズニングを利用して、42 の @tanstack/* パッケージにわたって 84 の悪意のあるバージョンを公開しました。このペイロードは、GitHub トークン、npm トークン、AWS/GCP/Azure の認証情報を窃取し、盗まれたトークンが失効した瞬間に ~/ を消去するデッドマンズスイッチデーモンをインストールします。
自分のいる環境に合ったエントリポイントを選択してください。
TAG=v1.0.0
curl -fsSLO https://github.com/fabriziosalmi/tanstack-compromise-checker/releases/download/$TAG/check.sh
curl -fsSLO https://github.com/fabriziosalmi/tanstack-compromise-checker/releases/download/$TAG/check.sh.sha256
sha256sum -c check.sh.sha256
bash check.sh --online
docker run --rm -v "$PWD":/scan \
ghcr.io/fabriziosalmi/tanstack-compromise-checker:v1.0.0 \
/scan true fail tanstack-findings.json '' GHSA-g7cv-rxg3-hmpx
イメージはマルチアーキテクチャ(linux/amd64、linux/arm64)で、GitHub OIDC による署名付きビルドの provenance(来歴証明)が付属しています。実行前に検証してください:
gh attestation verify \
oci://ghcr.io/fabriziosalmi/tanstack-compromise-checker:v1.0.0 \
--repo fabriziosalmi/tanstack-compromise-checker
permissions: {}
jobs:
check:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: fabriziosalmi/tanstack-compromise-checker@v1
with:
scan-dir: .
online: 'true'
fail-on: fail
完全にハードニングされたワークフローは .github/workflows/tanstack-check.yml にあり、このリポジトリ自身が自分に対して実行しているのと同じワークフローです。
| # | チェック | 説明 |
|---|---|---|
| 1 | デッドマンズスイッチ | ~/.local/bin/gh-token-monitor.sh、LaunchAgents + LaunchDaemons(macOS)、systemd ユーザー + システムユニット(Linux)、実行中のプロセス |
| 2 | 永続化 | シェルの rc ファイル、ユーザー/システムの crontab、/etc/cron.*、XDG オートスタート、グローバル git の core.hooksPath |
| 3 | 認証情報 | 機密環境変数、~/.npmrc、~/.yarnrc.yml、~/.aws/credentials、~/.config/gh/hosts.yml、~/.netrc、~/.docker/config.json、~/.kube/config、.env* ファイルの列挙 |
| 4 | ネットワーク IOC | 確立された外向き TCP 接続を持つ実行中の node プロセス(ヒューリスティック、手動レビュー) |
| 5 | リポジトリスキャン | package.json の宣言済み依存関係 + ロックファイルの固定バージョン(package-lock.json、yarn.lock、pnpm-lock.yaml) |
| 6 | インストール済み | node_modules/@tanstack/*/package.json を既知の悪意のあるバージョンリストと照合し、--online 時には npm レジストリの time[<version>] とも照合 |
| 7 | Actions のヒント | .github/workflows/* から pull_request_target、--ignore-scripts の欠落、actions/cache の使用をスキャン |
| 8 | Mini Shai-Hulud IOC | node_modules 内のペイロードファイル(router_init.js、tanstack_runner.js)、@tanstack/setup の optionalDependency、AI ツール設定の改ざん、ソース内の C2 ドメイン、攻撃者のコミット作成者 + ブランチパターン、身代金マーク付き npm トークン、二次的なワーム伝播パッケージ、さらに未知のペイロード形状に対する情報レベルのヒューリスティック |
--online を使用すると、スクリプトは実行時に GHSA アドバイザリも取得するため、検出カバレッジはハードコードされたバージョンリストではなく、アドバイザリの最新状態に追従します。
影響を受けるファミリー: @tanstack/router、@tanstack/react-router、@tanstack/history、@tanstack/start、@tanstack/eslint-plugin-router、および関連パッケージ。
影響を受けないファミリー: @tanstack/react-query、@tanstack/react-table、@tanstack/react-virtual、@tanstack/form、@tanstack/store。
# Quick check (current user's home)
bash check.sh
# Online mode: query the GHSA advisory and npm registry publish-time
bash check.sh --online
# Scan a specific directory
bash check.sh --scan-dir /path/to/your/repos
# JSON output for CI/SIEM integration
bash check.sh --json > findings.json
# Suggest pin commands for affected repos (dry-run)
bash check.sh --scan-dir /path/to/repos --fix
# Provide an extended known-bad list
bash check.sh --bad-versions-file ./extra-bad-versions.txt
| フラグ | 説明 |
|---|---|
--scan-dir DIR | スキャンするルートディレクトリ(デフォルト: $HOME)。/、/etc、/usr などのシステムディレクトリのスキャンは拒否します。 |
--online | GHSA アドバイザリと npm レジストリの time[<version>] を照会して侵害を確認します。デフォルトはオフ — オプトインです。 |
--ghsa GHSA-ID | --online で使用するアドバイザリ ID を上書きします(デフォルト GHSA-g7cv-rxg3-hmpx)。 |
--attack-window-start ISO、--attack-window-end ISO | --online で使用する公開時刻ウィンドウを上書きします。 |
--fix | 影響を受けるリポジトリに推奨される固定コマンドを出力します(デフォルトはドライラン)。 |
--apply | --fix と併用: 実行をオプトインします。現在も盲目的な update は拒否されます。手動での固定(ピン留め)が必要です。 |
--yes、-y | --apply の確認プロンプトをスキップします。 |
--json | 結果を JSON として stdout に出力します(--quiet を暗黙的に有効化)。 |
--bad-versions-file F | 既知の悪性リストにエントリ(pkg@version、1行に1つ)を追加します。 |
--no-color | ANSI カラーを無効にします。 |
--quiet、-q | チェックごとの出力を抑制し、サマリーのみを表示します。 |
-h、--help | ヘルプを表示します。 |
| コード | 意味 |
|---|---|
| 0 | クリーン — スキャン範囲内に指標なし |
| 1 | 警告のみ — レビュー推奨 |
| 2 | 失敗 — 侵害の指標が存在 |
| 3 | ツール/使用方法のエラー |
このリポジトリは、検出対象と同じ攻撃クラスから自身を防御しています。具体的には:
uses: は、浮動タグではなく 40 文字のコミット SHA に固定されています。permissions: {} を宣言し、ジョブは必要なものだけを付与します。actions/checkout は persist-credentials: false で呼び出されるため、認証済みの git リモートが $GITHUB_WORKSPACE に残りません。step-security/harden-runner はすべてのワークフローの最初のステップであり、ランナーの egress(外部通信)を監視します。main へのプッシュのたびに実行され、結果は SARIF としてアップロードされます。gh attestation でオフライン検証できます。check.sh.sha256 が同梱されています。完全なポリシーは SECURITY.md にあります。
しないでください: このツールを含むあらゆるセキュリティツールに curl | bash をパイプで渡さないでください。常にダウンロードし、チェックサムを検証し、確認してから実行してください。
━━ 1 / 8 DEAD-MAN'S SWITCH ARTEFACTS
✔ No dead-man's switch artefacts found
━━ 2 / 8 PERSISTENCE VECTORS
✔ No persistence vectors detected
━━ 3 / 8 TOKEN / CREDENTIAL EXPOSURE
✔ No credential exposure detected
━━ 4 / 8 NETWORK INDICATORS
✔ No node TCP connections currently established (or none observable)
━━ 5 / 8 REPO SCAN — package.json + lockfiles
ℹ Found 12 package.json + 8 lockfile(s)
✔ No compromised family declared in any package.json
✔ No compromised pins found in any lockfile
━━ 6 / 8 INSTALLED node_modules — direct version check
✔ No compromised packages in installed node_modules
━━ 7 / 8 GITHUB ACTIONS HARDENING HINTS
✔ No risky GitHub Actions patterns detected (in scanned scope)
━━ 8 / 8 MINI SHAI-HULUD PAYLOAD + AUXILIARY IOCs
✔ No Mini Shai-Hulud payload / auxiliary IOCs detected
━━ SUMMARY
Passed: 8 Warnings: 0 Failed: 0
Scope : /Users/alice/dev
✔ No indicators of compromise within scope: /Users/alice/dev
Note: a clean result for /Users/alice/dev does not certify the rest of the system.
デーモンを停止する前に GitHub トークンを失効させないでください — トークンが失効した瞬間にデッドマンズスイッチが
rm -rf ~/を実行します。
launchctl bootout gui/$UID ~/Library/LaunchAgents/com.user.gh-token-monitor.plistlaunchctl unload ~/Library/LaunchAgents/com.user.gh-token-monitor.plistsystemctl --user stop gh-token-monitor && systemctl --user disable gh-token-monitorrm -f ~/.local/bin/gh-token-monitor.sh~/.aws/credentials、~/.kube/config、~/.config/gh/hosts.yml、~/.npmrc を確認します。bash スクリプトに必要なもの:
bash 4+jq(推奨)— package-lock.json の解析用python3(オプションのフォールバック)— jq がない場合に使用curl — --online に必要lsof または ss(オプション)— ネットワーク IOC ヒューリスティック用