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

【ITニュース解説】How I Almost Got Pwned - A Tale of Supply Chain Attacks and GitHub Actions Gone Wrong

2025年09月12日に「Dev.to」が公開したITニュース「How I Almost Got Pwned - A Tale of Supply Chain Attacks and GitHub Actions Gone Wrong」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

開発者が、依存関係を悪用するサプライチェーン攻撃に遭遇した。悪意あるPRが、package-lock.jsonを改ざんし、GitHub Actions経由で機密情報窃取を狙った。これを防ぐには、依存関係の厳密な管理、CI/CD環境の保護、PRの慎重なレビューが不可欠だ。

ITニュース解説

Node.jsを用いたREST APIプロジェクトにおいて、偶然発見した不審なプルリクエストから、開発者を標的とした大規模なサプライチェーン攻撃の危機に直面した出来事があった。これは、現代のソフトウェア開発がどれほど容易に危険に晒されるかを示す事例である。

サプライチェーン攻撃とは、ハッカーがソフトウェアの依存関係、ビルドスクリプト、または継続的インテグレーション・継続的デリバリー(CI/CD)パイプラインなど、ソフトウェア開発の「供給経路」のどこかに悪意のあるコードや不正なプログラムを忍び込ませる攻撃を指す。個々のリポジトリを攻撃するよりも、多くのプロジェクトで共通して使われるツールやライブラリを一度に汚染することで、広範囲に影響を与えることが狙いである。普段、我々が信頼して使用しているオープンソースライブラリのアップデートなども、無意識のうちに悪意のあるコードを取り込んでしまうリスクがあるため、この種の攻撃は特に巧妙で危険性が高い。

攻撃の発端は、プルリクエストに含まれていたpackage-lock.jsonファイルの変更だった。このファイルは、プロジェクトが使用する依存パッケージのバージョンを厳密に記録し、ビルドの再現性を保証する重要な役割を持つ。しかし、このプルリクエストでは、依存パッケージのバージョン指定が具体的なバージョン番号(例: "1.17.0")からワイルドカード("*")へと変更されていた。ワイルドカードは、「任意のバージョンを許可する」という意味であり、これによってバージョン固定というセキュリティ対策が完全に無効化される。もし、これらのワイルドカード指定されたパッケージのいずれかが将来的に攻撃者によって侵害された場合、次にnpm installコマンドを実行した際に、悪意のあるバージョンが自動的にインストールされてしまう危険性があるのだ。

このロックファイルの変更と同時に提出されたのが、harshitcodez19という見慣れないユーザーからのプルリクエストであった。このプルリクエストは、GitHub Actionsを使ってCI/CDワークフローを追加するという内容で、一見するとプロジェクトに貢献しようとする初心者開発者の善意によるものに見えた。プルリクエストのコメントには誤字があったり、ワークフロー設定で間違ったブランチ名が指定されていたため、すぐに実行されることはないように見えた。しかし、これこそがGhostActionキャンペーンと呼ばれる、GitHubリポジトリを標的とした巧妙なサプライチェーン攻撃の一部であった。

GhostActionキャンペーンは、まず攻撃者が古い依存関係を持つリポジトリを特定することから始まる。次に、CI/CDワークフローの追加といった「親切な」プルリクエストを送信し、その中に意図的な間違いを含ませる。これにより、すぐにはワークフローが実行されず、メンテナンス担当者がその「間違い」を修正し、プルリクエストをマージするのを待つ。そして、修正されたワークフローが適切な権限で実行された際に、攻撃者の目的である認証情報やシークレットの窃取が行われる仕組みである。今回は、間違ったブランチ名によってワークフローがすぐに実行されないようにすることで、攻撃者が時間を稼ぎ、プロジェクトのメンテナンス担当者が「修正」してマージするのを待つという手口が使われた。

もしこの攻撃が成功していたら、どのような被害が生じていたか。ワイルドカード化されたロックファイルによって、npm installコマンドが悪意のあるパッケージをCI環境に導入し、その結果、CI環境に設定されていたGitHubのシークレット、AWSの認証情報、データベース接続文字列、APIキー、デプロイトークンなど、プロジェクトのインフラ全体を乗っ取るために必要なあらゆる情報が攻撃者の手に渡っていただろう。CI環境は通常、テスト、デプロイ、他のサービスとの連携のために高い権限を持っているため、その侵害は本番環境へのバックドア設置、顧客データの不正アクセス、仮想通貨マイニング、さらには他のシステムへの侵入など、非常に広範囲にわたる甚大な被害を引き起こす可能性があった。この攻撃は、2025年9月にセキュリティ研究者によって検出されたnpmパッケージの大規模なサプライチェーン攻撃の一部であり、攻撃者は正当なパッケージメンテナーのアカウントを侵害し、信頼されているパッケージに悪意のあるコードを注入していたという背景がある。

今回の事例から、いくつか見過ごしてはならない警告が明確になった。一つは、貢献者のプロフィールである。harshitcodez19というユーザーは貢献履歴がほとんどなく、使い捨てアカウントによく見られるようなランダムなユーザー名パターンであった。二つ目は、「間違い」の巧妙さである。ブランチ名の誤りや、npm install(依存関係を更新する可能性がある)をnpm ci(ロックファイルに固定されたバージョンを正確にインストールする)の代わりに使うなど、一見単なるミスに見えるが、これらは攻撃の意図を隠すための計算されたものであった。三つ目は、タイミングである。プルリクエストが提出された日付が、GhostActionキャンペーンの検出日と一致していた。これらの不審な兆候を見逃さないことが、セキュリティ対策において極めて重要である。

このようなサプライチェーン攻撃から身を守るためには、いくつかのベストプラクティスを徹底する必要がある。

第一に、ロックファイルの適切な管理と利用である。本番環境やCI/CD環境では、常にnpm ciコマンドを使用すべきである。これはpackage-lock.jsonに正確に記載されたバージョンの依存関係をインストールするため、予期しないバージョンの変更を防ぐ。また、ロックファイル内でのワイルドカードの使用は避け、常に具体的なバージョンを固定することが不可欠である。

第二に、CI/CDワークフローのセキュリティ強化である。GitHub Actionsのワークフローを構築する際は、常に最新バージョンのアクションを使用し、正確なブランチ名を指定する。依存関係のインストールにはnpm ciを使い、ビルド前にnpm audit --audit-level=criticalのようなコマンドでセキュリティ監査を実行し、既知の脆弱性がないかを確認する。

第三に、依存関係の定期的な管理である。npm outdatedで古いパッケージを確認し、npm auditでセキュリティ脆弱性をチェックする習慣をつける。可能な場合はnpm audit fixで脆弱性を自動修正し、常に依存関係を最新の状態に保つことが、攻撃のターゲットになりにくくする上で重要である。

第四に、プルリクエストの厳格なレビューガイドラインの確立である。特にCI/CD設定や依存関係に影響を与えるプルリクエストについては、貢献者の素性(過去の貢献履歴やプロジェクトとの関係)を確認する。変更の意図が明確であるか、不必要な権限を要求していないか、そして「初心者によるミス」に見える中に意図的な悪意が隠されていないかを注意深く精査する。

第五に、リポジトリの保護機能の活用である。GitHubのブランチ保護ルールを設定し、CI/CDワークフローの変更に対してもプルリクエストレビューを必須にする、ステータスチェックの合格を義務付ける、ワークフローを変更できるユーザーを制限するといった対策を講じる。また、Dependabotなどの自動ツールを活用して、依存関係の更新を定期的に提案させ、レビュープロセスに組み込むのも有効な手段である。

サプライチェーン攻撃の最も恐ろしい側面は、技術的な高度さだけでなく、開発者の「貢献者を助けたい」「信頼したい」という人間的な性質を悪用する点にある。無意識のうちに善意が攻撃の隙を生んでしまう可能性があるため、「信頼しても検証する」という姿勢が不可欠である。今回の経験は、セキュリティが単に安全なコードを書くだけでなく、開発パイプライン全体のあらゆる段階で意識されるべきであることを強く認識させるものとなった。オープンソースコミュニティはソフトウェア開発を豊かにするが、その力を賢く、そして安全に活用するためには、常に警戒心を怠らず、セキュリティに関する最新情報を学び続ける必要がある。

関連コンテンツ

関連IT用語