Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Zod Got Backdoored. Your Lockfile Didn't Save You, Luck Did.

2026年10月12日に「Dev.to」が公開したITニュース「Zod Got Backdoored. Your Lockfile Didn't Save You, Luck Did.」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

人気ライブラリZodにマルウェアが仕込まれたが、npmに公開されず被害は免れた。これは偶然の幸運であり、依存関係のセキュリティには常に注意が必要だ。インストールスクリプト無効化など、開発者は自身のシステムを守る対策を強化し、同様の攻撃に備えるべきである。

ITニュース解説

Zodは、JavaScriptの拡張言語であるTypeScriptで広く使われている、データの形をチェックするための人気ライブラリである。今回、このZodを含む複数のGitHubリポジトリで、悪意のあるプログラムが忍び込ませられそうになるという、セキュリティ上の大きな出来事があった。幸いにも大きな被害には至らなかったが、この一件は、私たちがソフトウェア開発において常に警戒すべき点を示唆している。

今回の事件は、人気のあるオープンソースプロジェクトのコードを管理するGitHubリポジトリに、攻撃者が悪意のある変更を加えようとしたことから始まった。具体的には、Zodのリポジトリ内に packages/zod/meta.test.mjs のように、一見するとテスト用のファイルに見える場所に、不正なコードが紛れ込ませられた。この悪意あるコードは、パッケージがインストールされる際に自動的に実行される「preinstall」や「postinstall」という仕組みを悪用することを意図していた。

攻撃者が仕込んだプログラム(ペイロード)は巧妙なものだった。もし実行されていれば、まずイーサリアムというブロックチェーン上で動く「スマートコントラクト」と呼ばれるプログラムに問い合わせを行う。このスマートコントラクトは、次の悪意のあるコードがどこからダウンロードされるべきかという情報を返す役割を担っていた。つまり、攻撃者はスマートコントラクトの情報を更新するだけで、標的となるコンピューターにダウンロードさせる悪意あるプログラムの内容や場所を、後から自由に変更できるようになっていた。これは、パッケージの中身だけをいくら確認しても、将来的にどんな危険なコードが実行されるかを予測できないという点で非常に危険な手口だった。ダウンロードされたコードは、最終的にユーザーのコンピューター上で実行され、証拠を隠すために自身の痕跡を消すようにも設計されていた。

しかし、幸いにもZodの悪意あるバージョンは、実際には広く使われているパッケージ管理システムであるnpmには公開されなかった。npmはパッケージが公開される際にセキュリティスキャンを行っており、同様の手口で攻撃された別のライブラリ(@nubjs/nub)の悪意あるバージョンを、ユーザーがインストールする前に阻止した。Zodの場合、メンテナー(開発・管理を行う人)が設定していた、パッケージ公開に対する非常に厳重なセキュリティ対策が決定的な役割を果たした。これは「信頼された公開」と呼ばれる仕組みや、GitHub上に特定の環境を設け、承認がなければ公開できないようにするなどの対策によって、リポジトリが侵害されても、実際に公開されるパッケージが汚染されることを防いだのである。さらに、攻撃者がpackage.jsonという設定ファイルに悪意あるスクリプトを記述する際にミスがあった可能性も指摘されており、この設定不備によってスクリプトがそもそも実行されなかったという偶然も重なったとされている。これらのいくつもの幸運が重なり、大規模な被害を免れることができたのだ。

この一件から私たちが学ぶべきは、今回の成功が単なる偶然に過ぎなかったという点である。攻撃者のわずかなミス、メンテナーの厳重なセキュリティ設定、そしてnpmのスキャン機能という、いくつもの防御壁がたまたま機能した結果にすぎない。これらのうち一つでも欠けていれば、今回の事件はもっと深刻な結果を招いていた可能性がある。過去にも、開発者の認証情報(パスワードやAPIキーなど)が乗っ取られ、人気のあるパッケージが悪意あるコードを含むバージョンとして公開されてしまうというサプライチェーン攻撃が頻繁に発生している。npm install コマンドを実行するということは、そのパッケージに含まれるコードが、あなたのコンピューター上で、あなたが持つ権限で実行されることを意味する。これは、SSHキー、AWSの認証情報、npmのトークン、シェル内の環境変数など、機密性の高い情報が盗み出される危険があるということだ。

このようなリスクから身を守るために、今すぐできる対策がいくつかある。まず、依存関係のインストールスクリプトをデフォルトで無効にすることを強く推奨する。これは、~/.npmrc やプロジェクト内の.npmrcファイルに ignore-scripts=true と設定することで可能だ。これにより、パッケージがインストールされる際に自動的に実行される可能性のある悪意のあるスクリプトを停止できる。ただし、sharpやbcryptなど、一部のパッケージは正しく動作するためにビルドプロセスが必要なため、これらはnpm rebuild <パッケージ名>のように手動で再ビルドする必要がある。ignore-scriptsは強力な対策だが、パッケージがbinエントリ(コマンド実行時に起動するプログラム)を登録することで攻撃される可能性もあるため、万能ではないことも理解しておくべきだ。

次に、新しいバージョンのパッケージが公開された直後のインストールを避ける「クールダウン」期間を設けることを検討する。攻撃者は新しいバージョンに悪意のあるコードを仕込むことが多いため、数日程度の待機期間を設けることで、セキュリティ上の問題が発覚する時間を稼げる可能性がある。さらに、package-lock.jsonというファイル内の"hasInstallScript": trueというエントリの追加を監視し、CI/CD(継続的インテグレーション/継続的デリバリー)環境で、新しいインストールスクリプトが追加された場合に人間によるレビューを必須とすることで、不審な変更を早期に発見できる。

もしあなたが自身でパッケージを開発・公開しているのであれば、Zodのメンテナーが実践していたような、公開プロセスの厳重なロックダウンは必須である。長期的に有効なnpmトークンを使用せず、OIDC(OpenID Connect)のような信頼された公開方法を採用し、GitHubの特定の環境では複数人の承認を必須とし、CIからの認証情報バイパスを防ぐための二要素認証(2FA)を徹底すべきだ。また、package-lock.jsonファイルをコミットし、npm ciコマンドを使って依存関係をインストールすることを徹底する。これにより、意図しないバージョンアップによるリスクを回避し、常に安定した依存関係を保てる。金曜日の夜などに、無計画なnpm updateを実行するのは避けるべき習慣である。

緊急のチェックとして、今すぐにでも自分のプロジェクトやシステムを確認するべきだ。例えば、悪意のあるドメインの一部(dsakldjklsaj33112)のような文字列が、node_modulesディレクトリ内やpackage-lock.jsonファイル内に存在しないかを検索する。もしこの検索で何かが見つかった場合、直ちにそのコンピューター上の全ての認証情報(パスワード、APIキーなど)を変更し、徹底的な調査を行う必要がある。また、package-lock.json内の"hasInstallScript": trueというエントリの数をチェックし、不審に多い場合はレビューを検討することも有効だ。

今回のZodの事件は、ソフトウェアサプライチェーン攻撃が現実の脅威であり、誰にでも起こりうる問題であることを改めて示した。しかし、同時に、Zodのメンテナーが導入していたような適切なセキュリティ対策が、実際に攻撃を防ぐ上で非常に効果的であることも証明した。パッケージの公開範囲を制限する設定、npmによるスキャン、そしてインストール時に意図しないコードが実行されないようにする対策は、どれも私たちが今すぐにでも導入できるものばかりだ。攻撃者はすでにブロックチェーンのような新しい技術を悪用している。あなたの~/.npmrcにignore-scripts=trueの一行を追加することは、その第一歩として、今日中にでも実行すべき重要なセキュリティ対策である。

関連コンテンツ

関連IT用語

関連ITニュース