1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Shai-Hulud攻撃対応:5分でできるnpm依存関係の更新日を確認するbashスクリプト

Posted at

背景

2025年9月、CrowdStrike の npm パッケージ群が侵害されるという重大なサプライチェーン攻撃が発生しました。
この攻撃は 「Shai-Hulud攻撃」 と呼ばれ、以前に tinycolor を含む40以上のパッケージを侵害したキャンペーンの延長線上にあります。

攻撃内容は以下の通りです:

  • bundle.js を挿入し、TruffleHogで認証情報をスキャン
  • 環境変数から GITHUB_TOKEN, NPM_TOKEN, AWS_ACCESS_KEY_ID などを窃取
  • GitHub Actions のワークフローを不正に生成し、外部エンドポイントへ送信
  • 感染を自己伝播させる挙動を持つ

npmレジストリは速やかに侵害パッケージを削除しましたが、プロジェクトが影響を受けていないか確認することが重要です。

この事件を調査・分析を行った Socket社 は対応策として次の内容をブログ記事に公開しています。

Immediate Guidance#

  • Uninstall or pin to known-good versions until patched releases are verified.
  • Audit environments (CI/CD agents, developer laptops) that installed the affected versions for unauthorized publishes or credential theft.
  • Rotate npm tokens and other exposed secrets if these packages were present on machines with publishing credentials.
  • Monitor logs for unusual npm publish or package modification events.
    出典: socket.dev Blog

特に1点目の「known-good versions に固定する」に対応するためには、まず侵害が初めて観測された日(2025年9月14日)以降に更新された依存関係を洗い出すことが重要です。

この記事で紹介すること

本記事では、bashスクリプトを用いて以下の2点を簡易的に検査する方法を紹介します。

  1. プロジェクトで使用されている npm 依存関係の更新日が2025年9月14日より前であること確認
  2. (念のため、)既知の流出エンドポイント webhook.site が node_modules や GitHub Actions ワークフローに含まれていないことを確認

事前準備

スクリプトの実行には以下のコマンドラインツールを使用しています。
ご使用のOSに合わせて適宜インストールしてください。

  • jq: 軽量で柔軟なコマンドライン用 JSON プロセッサです
  • ripgrep: 行指向の検索ツールで、現在のディレクトリ以下を再帰的に正規表現パターンで検索します

実際のスクリプト

npm-supplychain-check.sh
#!/usr/bin/env bash

RED="\033[31m"
GREEN="\033[32m"
RESET="\033[0m"

echo "This script helps validate exposure against the ongoing supply-chain attack described by:"
echo "  https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages"
echo "Checks:"
echo "  1) Ensure no known exfiltration endpoint (webhook.site) exists in current node_modules or GitHub Actions workflows."
echo "  2) Ensure each dependency version in use was published BEFORE the first observed compromise date."
echo ""

if ! command -v jq >/dev/null 2>&1; then
  echo -e "Error: jq is required. Please install it from https://stedolan.github.io/jq/." >&2
  exit 1
fi

if ! command -v rg >/dev/null 2>&1; then
  echo -e "Error: ripgrep (rg) is required. Please install it from https://github.com/BurntSushi/ripgrep." >&2
  exit 1
fi

echo "Searching node_modules for webhook.site..."
if ! rg -n --no-ignore --hidden -g 'node_modules/**' -e 'webhook\.site' > /dev/null; then
  echo -e "No webhook.site found in node_modules: ${GREEN}OK${RESET}"
fi
echo ""

echo "Searching GitHub Actions workflows for webhook.site..."
if ! rg -n --no-ignore --hidden -g '.github/workflows/*.y*ml' -e 'webhook\.site' --no-messages > /dev/null; then
  echo -e "No webhook.site found in GitHub workflows: ${GREEN}OK${RESET}"
fi
echo ""

CUTOFF="2025-09-14T00:00:00.000Z"
echo "Checking npm dependencies against cutoff date: ${CUTOFF}"
npm ls --json --all \
  | jq -r '
      .. | .dependencies? // empty
      | to_entries[]
      | select(.value.version)
      | "\(.key) \(.value.version)"
    ' \
  | sort -u \
  | while read -r name ver; do
      modified=$(npm view "$name@$ver" "time[$ver]")
      if [[ "$modified" < "$CUTOFF" ]]; then
        echo -e "$name@$ver $modified: ${GREEN}OK${RESET}"
      else
        echo -e "$name@$ver $modified: ${RED}NG${RESET}"
      fi
    done

実行方法

  1. 上記スクリプトをコピーして、 npm-supplychain-check.sh などの名前をつけて保存します

  2. 実行権限を付与します

    bash
    chmod +x check-shai-hulud.sh
    
  3. 保存したスクリプトを実行します

    bash
    ./npm-supplychain-check.sh
    

実行結果の例:

This script helps validate exposure against the ongoing supply-chain attack described by:
  https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages
Checks:
  1) Ensure no known exfiltration endpoint (webhook.site) exists in current node_modules or GitHub Actions workflows.
  2) Ensure each dependency version in use was published BEFORE the first observed compromise date.

Searching node_modules for webhook.site...
No webhook.site found in node_modules: OK

Searching GitHub Actions workflows for webhook.site...
No webhook.site found in GitHub workflows: OK

Checking npm dependencies against cutoff date: 2025-09-14T00:00:00.000Z
Checking @azure/abort-controller@2.1.2...
@azure/abort-controller@2.1.2 2024-04-11T00:52:03.863Z: OK
Checking @azure/core-auth@1.10.1...
@azure/core-auth@1.10.1 2025-09-11T18:26:08.654Z: OK
Checking @azure/core-client@1.10.1...
@azure/core-client@1.10.1 2025-09-11T19:04:27.903Z: OK
Checking @azure/core-http-compat@2.3.1...
@azure/core-http-compat@2.3.1 2025-09-11T19:13:11.398Z: OK
...

実行結果で webhook.site が検出されたファイル や NG と表示された依存関係 がある場合、既に侵害されている可能性があります。
本記事で紹介したスクリプトを活用し、対象を洗い出すことで、詳細な調査やバージョン固定(pin)などの対応を検討する第一歩としてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?