AsyncAPIのnpmパッケージにMiasma混入、正規の公開経路を悪用した供給網攻撃への対応

ソフトウェア供給網の検査工程で不審なパッケージを隔離する様子を表した抽象イラスト

AsyncAPIの正規npmパッケージ4種、計5バージョンに不正コードが混入し、正規のGitHub Actions公開工程を通じて配布される供給網攻撃が確認されました。

Unit 42の調査JFrog Security Researchの解析によると、2026年7月14日に公開された対象版は、モジュールが読み込まれた際にMiasma系の遠隔操作用コードを取得し、開発者端末やCI実行環境に常駐する可能性があります。

対象版を導入した組織は、パッケージを削除するだけで終えず、コードが実行されたかを調べ、必要に応じて端末の隔離、認証情報の更新、ビルド成果物の再検証まで進める必要があります。

対象となる4パッケージと5バージョン

確認された不正バージョンは次のとおりです。

パッケージ 不正バージョン 確認の要点
@asyncapi/generator 3.3.1 生成処理や関連ツールから読み込まれた可能性を確認
@asyncapi/generator-helpers 1.1.1 直接依存と推移的依存の両方を確認
@asyncapi/generator-components 0.7.1 ビルド環境や文書生成環境も確認
@asyncapi/specs 6.11.26.11.2-alpha.1 パーサーなどを介した推移的な導入に注意

OSVにも悪意ある@asyncapi/generator 3.3.1の記録が公開されており、該当版と既知の安全版を機械的に照合できます。

執筆時点のnpmレジストリでは、不正な5バージョンはバージョン一覧から削除され、既定版は@asyncapi/generator 3.3.0@asyncapi/specs 6.11.1@asyncapi/generator-helpers 1.1.0@asyncapi/generator-components 1.0.0を指しています。

ただし、レジストリから削除されても、社内キャッシュ、既存のnode_modules、コンテナイメージ、過去のCI成果物に対象版が残っている可能性があります。

正規の公開工程から不正コードが届いた理由

この攻撃では、偽名のパッケージを利用者に選ばせるタイポスクワッティングではなく、AsyncAPIの正規パッケージと公開工程が悪用されました。

AsyncAPIの公式リポジトリには、名義が「Your Name」とされた未署名の不審コミットが残っており、難読化されたコードとバージョン変更を確認できます。

JFrogの分析では、公開を起動するブランチへの不正な直接書き込みを契機に、正規のGitHub ActionsとnpmのOIDC連携がパッケージを公開しました。

そのため、配布物には正規工程で作られたことを示す来歴情報が付きましたが、「公開元の工程を通ったこと」は「ソースコードが安全であること」を保証しません。

公開ブランチへの書き込み権限、承認規則、署名、ワークフロー権限を一体として守らなければ、正規の署名付き工程が攻撃者の配布経路になります。

インストール履歴だけでは感染を断定できない

今回の不正コードは、preinstallpostinstallのようなインストール用スクリプトではなく、対象モジュールがrequire()またはimportされたときに動くよう仕込まれていました。

したがって、npm install --ignore-scriptsを使っていても、この実行経路を止められません。

一方、対象版がロックファイルに記録されているだけでは、不正コードが実行された証拠にはなりません。

開発端末、CIランナー、文書生成処理、テスト、コンテナビルドのいずれかが対象モジュールを実際に読み込んだかを、ジョブログ、依存関係、キャッシュの時刻、実行プロセス、通信記録から確認します。

管理者が進める調査と封じ込め

  1. 対象版を検索するpackage-lock.jsonnpm-shrinkwrap.json、Yarnやpnpmのロックファイル、SBOM、アーティファクト保管庫、依存関係キャッシュから5バージョンを検索します。
  2. 実行された環境を切り分ける:対象版を取得した時間帯だけでなく、その後にモジュールを読み込んだ端末、CIランナー、コンテナビルドを特定します。
  3. 不審な痕跡を調べる:JFrogが示したsync.jsmiasma-monitor.miasma配下のファイル、IPFSへの取得通信、既知の指令サーバー向け通信を確認します。
  4. 影響環境を隔離する:実行が確認された端末や、調査範囲を確定できない共有ランナーはネットワークから切り離し、既知の正常なイメージから再構築します。
  5. 認証情報を安全な端末から更新する:npm、GitHub、クラウド、SSH、コード署名、デプロイ、CIで利用できたトークンや鍵を失効させ、影響を受けていない端末から再発行します。
  6. 下流の成果物を検証する:対象環境が作成または公開したパッケージ、コンテナ、文書サイト、配布ファイルを洗い出し、正常な依存関係から再生成します。

痕跡が見つからない場合も、「侵害がなかった」と直ちに結論づけることはできません。

ログの保存期間が短い、共有ランナーが再利用されている、ネットワーク記録がないといった条件では調査に限界があるため、認証情報の失効と環境の再構築を優先した方が安全です。

公開工程の再発防止策

再発防止では、既定ブランチだけでなく、npmへの公開を起動できるすべてのブランチを本番環境として扱います。

  • 公開ブランチへの直接書き込みを禁止し、複数人のレビューを必須にする
  • 署名付きコミットを要求し、管理者による規則回避も制限する
  • GitHub Actionsの権限を最小化し、外部から来たコードに書き込み用トークンを渡さない
  • 公開直前に差分と生成物を検査し、重要パッケージには人による承認を加える
  • 依存関係の更新を一定時間保留し、公開直後の版が自動で本番ビルドへ入らないようにする
  • CIからの外向き通信を制限し、パッケージが不要な取得先へ接続した場合に停止させる

来歴情報や署名は、公開経路の追跡には役立ちますが、レビュー、ブランチ保護、実行時監視の代わりにはなりません。

今回の事案は、依存関係の安全性を「どこから届いたか」だけで判断せず、「誰が公開を起動できるか」「何が実行されたか」「どこへ通信したか」まで連続して管理する必要性を示しています。

出典

投稿者 greeden Inc.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)