TITLE

CrowdSecのソースコード露出で分かった、npmサプライチェーン『三段仕掛け』の手口

投稿日:2026.09.18

CATEGORY

  • Web開発
CrowdSecのソースコード露出で分かった、npmサプライチェーン『三段仕掛け』の手口

2026年9月17日、セキュリティ企業CrowdSecが「ソースコードの一部を第三者に読み取られていた」と公表しました。原因はCrowdSec自身の設定ミスではなく、利用していたnpmパッケージ(TanStack由来のコンポーネント)がサプライチェーン攻撃でバックドア化されていたことだと、CrowdSecは説明しています。影響は非公開リポジトリ約170個・公開リポジトリ130以上の計約300個に及びましたが、顧客データやPIIは対象外だったとCrowdSecは説明しています。

CrowdSecが公表した「ソースコード露出」の中身

漏洩が発生したのは2026年5月で、悪用可能だったのは短い時間枠のみでした。CrowdSecが利用していたTanStack由来のコンポーネントがバックドア化されており、そこからCrowdSecの非公開コードベースへの読み取り権限を持つAPIキーが抽出されました。CrowdSecはこの経路について、Mistral AIの事例と同様のものと考えられると述べています。

影響範囲は非公開リポジトリ約170個(公開リポジトリ130以上を含めると計約300個)で、SaaS管理画面のコード・AWS処理コード・コネクタ・自動化ツールが含まれます。一方で、顧客データ、ログイン認証情報、組織情報などの個人識別情報(PII)は対象外でした。CrowdSecは顧客ログやPIIを保存していないと説明しています。対応としては、必要なトークン・認証情報を直ちにローテーションし、横展開(lateral movement)が可能なトークン等が残っていないかを迅速に調査したとのことです。

背景にあるnpmエコシステムの攻撃 — TanStackへのサプライチェーン攻撃

CrowdSecの発表そのものは、TanStack由来のコンポーネントがバックドア化されていたという経緯までしか明らかにしていません。ただし時期・対象とも一致する攻撃を、セキュリティ企業Snykが独自に技術分析しています。Snykによると、攻撃は2026年5月11日19:20〜19:26 UTCという短い時間に発生しました。84個の悪意あるnpmパッケージアーティファクトが@tanstack名前空間の42パッケージに配布され、その後200以上のパッケージへ拡大したといいます。

この攻撃は、自己伝播型npmサプライチェーン攻撃キャンペーン「Shai-Hulud」の第4波と位置づけられています。Snykの分析では、2025年9月の第1波(自己伝播ワームの初出現)、2025年11月の第2波(プリインストールフックとホームディレクトリ破壊)、2026年4月の第3波(AIコーディングエージェントへの永続化)に続く今回の第4波は、有効なSLSA Level 3証明付きの悪意パッケージが初めて確認されたという点が特徴です。攻撃者はTeamPCP(別名DeadCatx3、PCPcat等)と帰属され、全波を通じて同じ暗号技術(Fisher-Yates PRNG)が使われているといいます。

三段仕掛けの侵入 — Pwn Request→キャッシュポイズニング→OIDCトークン窃取

正規の証明書付きで悪意あるパッケージが配布されるまでには、3段階の仕込みがありました。

Pwn Request(フォークによる侵入)→キャッシュポイズニング(vite_setup.mjsによるpnpmストア汚染)→OIDCトークン窃取(Runner.Workerからのトークン抽出とnpm publish)という三段仕掛けの攻撃チェーンを、背骨状のステップ図で示す概念図。

1段目は「Pwn Request」と呼ばれる初期侵害です。攻撃者は"zblgg"という名のフォークアカウントを作成し、pull_request_targetトリガーを使うワークフローの脆弱性を悪用しました。このトリガーはbaseリポジトリのセキュリティコンテキストで実行されるため、フォーク側のコードがbaseリポジトリのキャッシュスコープにアクセスできてしまいます。

2段目はGitHub Actionsのキャッシュポイズニングです。フォーク側の悪意あるvite_setup.mjsが、後でrelease.ymlが検索する正確なキーを事前計算し、pnpmパッケージストアを汚染しました。この1.1GBの悪性キャッシュエントリは、8時間以上検出されずに残存したといいます。

3段目でOIDCトークンが抽出されます。攻撃者はRunner.Workerプロセスのアドレス空間をダンプしてOIDCトークンを抜き出し、正当なTanStackリリースワークフローとしてnpmに直接パッケージを発行しました。フォークから始まった侵害が、最後は「本物のリリース」としてnpmレジストリに着地する——これが三段仕掛けの全体像です。

見つかりにくさの正体 — 1.1GBのキャッシュが8時間検知されなかった理由

倉庫の棚に並んだ同じ形の梱包箱の中に、1つだけ色の違う箱が紛れ込んでいるフラットイラスト。汚染されたキャッシュが正常なキャッシュに紛れて長時間見つからなかったことを表す。

この手口が厄介なのは、どの段階も「異常な行為」として単体では目立たない点にあります。フォークからのプルリクエストは日常的に飛んできます。ビルドキャッシュの更新も、CIが正常に動いている証拠として扱われます。OIDCトークンの発行も、正規のワークフローが実行された結果として起きます。3つとも個別には正常な出来事に見えるからこそ、悪性キャッシュは8時間以上そこにあり続けました。

私たちも、AIエージェントを含む自動化された処理に対しては「注意喚起の張り紙」で終わらせず、危険な操作をコード側で機械的に拒否する仕組みを運用方針としています。保護対象のリポジトリへの直接pushや、設定ファイルの書き換えを機械的に止める、といった具合です。対象とする仕組みそのものは異なりますが、性善説の運用でなく構造で制約するという設計思想は共通します。フォークの実行権限・キャッシュの汚染耐性・トークンの発行範囲も、最初から狭く設計しておく対象だと言えます。

今日から確認できること — 3つのチェックポイント

  • pull_request_targetを使うワークフローの権限を棚卸しする: フォーク側のコードをbaseリポジトリのセキュリティコンテキストで実行していないか、シークレットへのアクセスが必要以上に広くないかを確認します
  • CI/CDのキャッシュ機構を「常に信頼できるもの」として扱っていないか見直す: GitHub Actions cacheやpnpmストアのようなキャッシュは、ビルドを速くする一方で、汚染されても気づきにくい経路になります
  • OIDCトークンの発行範囲(id-token: writeの付与範囲)を点検する: リリースワークフローが必要以上に広い権限でOIDCトークンを発行していないか、発行対象のジョブを絞れているかを確認します

まとめ

パッケージの出どころや証明書を信頼するだけでは見抜けず、CI/CDの実行権限そのものを疑う視点が要ります。まずはワークフロー1つ、pull_request_targetを使っているかどうかを確認するところから始められます。

関連

自社サイトの状態が気になったときは、URL を入れるだけで使える無料の診断ツールを公開しています。

出典

※ この記事は AI を使用しています。Leadeas が自社開発した AI エージェント基盤で下書きを作成し、人間のレビューを経て公開しています。AI ネイティブ開発会社として自社の技術をそのまま実演する目的で、この手法を用いています。(詳しくは AI 利用ポリシー)

AI

AI導入やシステム開発の ご相談を承っています。

お気軽にお問い合わせください

無料相談する

お問い合わせには1営業日以内にご返信します