はじめに
2025年9月に発覚した事故増殖型マルウェア Shai-Hulud の対策として、
@aikidosec/safe-chain をプロジェクトに導入しました。
この記事では、具体的にどんなセキュリティ対応を行なったのかを紹介します。
対応内容
早速対応内容から紹介します。
サクっと対応内容だけ知りたい方は、この章だけいただければOKです。
対応1:開発メンバーのホストマシンにインストール
1️⃣ グローバルインストール
npm install -g @aikidosec/safe-chain
2️⃣ シェル統合を設定
safe-chain setup
その後、ターミナルを再起動します。
3️⃣ テストで動作確認
$ npm install safe-chain-test
✖ Malicious changes detected:
- safe-chain-test@0.0.1-security
Exiting without installing malicious packages.
これが出ればOKです。
(=マルウェア検知が正常に働いた状態)
対応2:CI/CD環境(Dockerfile)に組み込み
※この対応は公式ドキュメントには明記されていません。
GitHub Actions 経由で Docker ビルドを行う場合は、以下のように記述します。
# Dockerfile
RUN npm install -g @aikidosec/safe-chain && \
safe-chain setup-ci && \
export PATH="$HOME/.safe-chain/shims:$PATH" && \
yarn install --frozen-lockfile
💡 補足
$HOME/.safe-chain/shims にパスを通すのは、
GITHUB_PATH 環境変数が存在する場合のみ自動で PATH を設定する仕組みになっているためです(該当コードはこちら)。
.github/workflows 内で直接実行する場合、ドキュメントの内容を参照してください。
対応予定: パッケージマネージャーをpnpm v10に移行する
Shai-Huludはパッケージのライフサイクルスクリプトに悪意のあるスクリプトを仕込んで、攻撃してきます。
pnpm v10は、デフォルトでライフサイクルスクリプトを実行しない仕様になっており、
ライフサイクルスクリプトが必要なパッケージは、ホワイトリストを追加しておく必要があります。
{
"pnpm": {
"onlyBuiltDependencies": ["puppeteer", "necessary-package"]
}
}
とはいえ、ここに指定しているパッケージが感染したらアウトなんですが、被害経路は狭められるということですね。
今後プロジェクトを立ち上げる際は、pnpmを使っていこうと思っています。
💣 Shai-Hulud 騒動とは?
有名パッケージ開発者 Josh Junon 氏がフィッシングメールによりアカウントを乗っ取られ、悪意あるスクリプトを npm パッケージに注入されてしまいました。
被害は毎週26億回以上ダウンロードされるパッケージ群に及んだとか及ばないとか。。
support@npmjs.comではなくsupport@npmjs.helpという偽ドメインから送られたメールが原因のようです。
教科書に出てきそうなシンプルな手口、、、、。
明日は我が身です!
センシティブな入力が求められるメールには細心の注意を払いましょう。
🔍 その他の攻撃手法
Typosquatting(タイポスクワッティング)
# 正しいパッケージ ✅
npm install typo-squatting
# 悪意のあるパッケージ ❌
npm install typo-suqatting
似た名前のパッケージを紛れ込ませる攻撃です。
開発中に気付ける自信がありますか?私はないです!
Dependency Confusion(依存関係の混乱)
社内専用で作るようなプライベートパッケージと、同名のパブリックパッケージを登録してすり替える攻撃です。
プライベートレジストリの優先設定がないと、公開の悪意あるパッケージが先に解決されてしまいます。
タイポスクワッティングの上位互換のような仕組みですね。社内専用パッケージを導入するような大きな組織は考慮されていそうですが、これからの導入していくプロジェクトは気を付けたいポイントです。
Hallucination Squatting(幻覚スクワッティング)
生成AI(ChatGPT, Claude, Cursorなど)が存在しないパッケージを提案し、攻撃者がその名前で本物っぽいパッケージを登録して待ち構える手口です。
# LLMが幻覚で提案したコマンド
npm install express-auth-helper
# → 実は存在しないはずのパッケージ
🛡 safe-chainで守る
みなさま、様々な手口を知り震え上がっているところかと思います。
そこで冒頭に紹介した@aikidosec/safe-chain をお勧めします。
safe-chain は npm/yarn コマンドをラップして、インストール時にマルウェアスキャンを自動実行します。
# 異常を検知するとインストールに失敗
$ npm install safe-chain-test
✖ Malicious changes detected:
- safe-chain-test@0.0.1-security
Exiting without installing malicious packages.
これにより、仮にタイポスクワッティングや幻覚スクワッティングに引っかかったとしても、不正パッケージの混入を未然に防げます。
今回は細かい説明を省きますが、仕組みとしてはnpmに上がったパッケージをaikido社がスキャンしてリストとして持っており、safe-chainはそのデータベースとインストールしようとしているパッケージを照合しているようです。
また、これがあるから100%安全ということはありません。過信せずにどこにでも危険が潜んでいるという意識を持ちましょう。
以上です。
まとめ
- safe-chainをローカルとCI環境に入れよう
- pnpmに移行しよう
- 100%安全という状況はない
それでは良いエンジニァ🐈ライフを!