Upgrade to Pro — share decks privately, control downloads, hide ads and more …

axios, LiteLLM...不使用だったのでOK、ではない。「次に備える」ソフトウェアサ...

Avatar for GMO Flatt Security GMO Flatt Security
April 07, 2026
280

axios, LiteLLM...不使用だったのでOK、ではない。「次に備える」ソフトウェアサプライチェーン侵害への対策

弊社ウェビナー ( https://flatt.tech/takumi/event/github-actions-compromise-202603 ) におけるCTO米内の講演資料です。
動画はこちら ( https://www.youtube.com/watch?v=ms8MkNmiejA )

Avatar for GMO Flatt Security

GMO Flatt Security

April 07, 2026

More Decks by GMO Flatt Security

Transcript

  1. 米内 貴志(よねうち たかし) 仕事&趣味: ものづくりを安全にすること 2019年〜 Flatt Security('21〜 CTO) 著書『Web

    ブラウザセキュリティ』等 セキュリティ・キャンプ '12 参加, '18-'24 スタッフ等 未踏ターゲット '21 / Quantum-Classical Programming Language ICC '23 アジア代表 / Head Captain CODE BLUE レビューボード '24-'25 自己紹介 © GMO Flatt Security Inc. All Rights Reserved. 2 / 52
  2. 2026年3月、パッケージレジストリを標的とした侵害が相次いだ 事案 日付 エコシステム Trivy Action 侵害 3/19 GitHub Actions

    LiteLLM 侵害(Trivy から連鎖) 3/24 PyPI Telnyx 侵害(Trivy から連鎖) 3/27 PyPI axios 侵害 3/31 npm Trivy → LiteLLM → Telnyx はクレデンシャル窃取を介して連鎖的に発生した axios は時系列的に近接しつつも、独立して発生した事象と捉えられている この潮流の中、「今回を自社では使っていなかったので大丈夫だった」で済ませてよいのか? この問いが本ウェビナーの主題であり、結論筆者の答えは「ノー」である為、必要な対策を論じたい 2026年3月のソフトウェアサプライチェーン侵害 © GMO Flatt Security Inc. All Rights Reserved. 5 / 52
  3. npm 上でも利用トップクラスのパッケージが侵害され、約3時間マルウェアが配られた事案 指標 数値 axios の週間ダウンロード数 1億超 axios に依存する npm

    パッケージ数 174,000 悪性バージョンが公開されていた時間 約3時間(00:21 - 03:15 UTC) axios の普及率 クラウド / コード環境の約 80% に存在とも言われる(Wiz) 1.14.1 (latest タグ)と 0.30.4 (legacy タグ)の2バージョンが同時に公開された ^1.x 利用者にも ^0.x 利用者にも刺さる構成 約3時間で npm が除去。コミュニティの collaborator が侵害に気づき対処した この3時間に npm install を実行した環境は、RAT がデプロイされた可能性がある axios 侵害(3/31): 概要 © GMO Flatt Security Inc. All Rights Reserved. 8 / 52
  4. 攻撃は約2週間前からのソーシャルエンジニアリングに始まった(axios/axios#10636) ~3/17 S.E. 開始 メンテナに対する ソーシャルエンジニアリング 3/30 05:57 準備 plain-crypto-js

    v4.2.0 公開(無害) 3/31 00:21 攻撃 [email protected] 公開(悪性) 3/31 ~01:00 拡大 [email protected] 公開 コミュニティ Issue 削除 3/31 01:38 対応 DigitalBrainJS が deprecate + npm 連絡 3/31 03:15 除去 npm が悪性 バージョン除去 攻撃の約2週間前からソーシャルエンジニアリングが開始されていた メンテナ端末に RAT が仕込まれ、npm アカウントの認証情報が窃取された 侵害を報告する Issue が投稿されるたびに、攻撃者が侵害済みアカウントで削除した 別の collaborator(DigitalBrainJS)が気づき、deprecate と npm への直接連絡で対処した axios 侵害(3/31): タイムライン © GMO Flatt Security Inc. All Rights Reserved. 9 / 52
  5. マルウェア混入後も .js ファイルは正規版と同一。package.json の1行のみが差分 { "name": "axios", "version": "1.14.1", "dependencies":

    { + "plain-crypto-js": "^4.2.1" } } plain-crypto-js は正規の crypto-js を模倣した名前の悪性パッケージ 前日に無害な v4.2.0 を公開してレジストリ上の履歴を作り、直前に v4.2.1(悪性)を差し替えた v4.2.1 の postinstall スクリプトが npm install 時に自動実行された 目新しいわけではなく、event-stream の侵害を含め、過去にも用いられた手法 axios 侵害(3/31): 悪性コードの注入方法 © GMO Flatt Security Inc. All Rights Reserved. 10 / 52
  6. 典型的な postinstall スクリプトで発火する。内容自体は所謂な RAT ステージ 動作 ドロッパー ( setup.js )

    Base64反転 + XOR で復号し、C2 sfrclak[.]com:8000 に接続する RAT ダウンロード OS を判定し、Win / macOS / Linux 別の RAT をダウンロードする RAT 実行 クレデンシャル窃取 + リモートアクセスを確立する RAT が入れば遠隔からスクリプト実行・バイナリ注入・ファイル列挙が可能になる 実質的に端末を掌握された状態 クレデンシャル窃取にとどまらない GTIG はドロッパーを SILKBELL、RAT を WAVESHAPER.V2 と分類している(GTIG) axios 侵害(3/31): 悪性コード plain-crypto-js の概要 © GMO Flatt Security Inc. All Rights Reserved. 11 / 52
  7. setup.js は実行後にファイルを差し替え、侵害の痕跡を消去した 実行 setup.js 実行 postinstall で RAT をデプロイする →

    自己削除 setup.js 削除 setup.js 自身を ファイルシステムから削除する → 偽装 package.json 差替 事前に用意した無害な package.md を package.json に リネームする 実行後に setup.js を削除し、package.json を無害な内容に差し替える node_modules/plain-crypto-js/ の中身を事後に見ても、マルウェアの痕跡が残りにくい 簡易的ではあるが、調査を面倒にするような工夫が見られると言える axios 侵害(3/31): 悪性コード plain-crypto-js の特徴 © GMO Flatt Security Inc. All Rights Reserved. 12 / 52
  8. RAT のインフラと検体の特徴から、国家支援型(DPRK)の攻撃と帰属されている ベンダ 分類名 一次ソース Google GTIG UNC1069 GTIG Blog

    Microsoft Sapphire Sleet Microsoft Security Blog Sophos NICKEL GLADSTONE Sophos Blog 各ベンダとも、過去に追跡してきた RAT や C2 インフラとの類似性を根拠としている 我々目線でも、npm 空間内にある過去の行動・他検体群とも緩やかに整合している印象 axios 侵害(3/31): 帰属分析 © GMO Flatt Security Inc. All Rights Reserved. 13 / 52
  9. axios チームは Post Mortem(axios/axios#10636)で学びをシェアしている 「個人アカウントからの直接 publish はリスクだった」 と述べられている OIDC フローと

    immutable release のセットアップが事前に導入されているべきだった v1.* はキーレス公開・v0.x 側にトークン公開されていて、Weakest chain が悪用された事例である なお v0.x 側もキーレスになっている: https://github.com/axios/axios/pull/10639 「不正な publish を自動検知する仕組みがなかった」 とも述べられている 検知はコミュニティの目撃に完全に依存していた 攻撃者が Issue を削除したことで、検知がさらに遅れた なお Issue 削除等の妨害工作は他侵害でも見られている 「高影響パッケージのメンテナは、高度なソーシャルエンジニアリングの標的になる」 依存網は既に攻撃に値する対象と理解されている、と解釈すべきである 当然パッケージ・OSSの提供元に対する帰責は合理的でない axios 侵害(3/31): メンテナによる Post Mortem からの教訓 © GMO Flatt Security Inc. All Rights Reserved. 14 / 52
  10. 以下の 3 つを理由として、不使用だから OK とは言い難い 理由 1: 直接依存には含まれていない場合でも、推移的依存には含まれている可能性がある 理由 2:

    攻撃スキームは「再利用」可能。今後も、axios 以外の侵害リスクが高い状態にある 理由 3: AIへの移譲が進む中、今後、依存を把握できていないシナリオは増えていく 考察: なぜ「 (axios は)不使用だからOK」ではないのか © GMO Flatt Security Inc. All Rights Reserved. 16 / 52
  11. Direct dependency だけが依存ではない 自分が npm install したパッケージが依存しているパッケージも、自分の依存になる あなたのプロジェクト ├── gatsby@^5.0.0

    ← Direct dependency (自分で選んだ) │ └── axios@^1.6.4 ← Transitive dependency (gatsby が選んだ) │ ├── follow-redirects@^1.15.11 │ ├── form-data@^4.0.5 │ │ ├── asynckit@^0.4.0 │ │ ├── ... │ └── proxy-from-env@^2.1.0 └── twilio@^5.0.0 └── axios@^1.13.5 ← ここにも axios あなたのプロジェクトは axios を package.json に書いていなくても、axios に依存しうる つまり誰かが axios@^1.x に依存しているだけで、今回の侵害の影響を受けていた可能性がある 理由 1: 膨大な推移的依存(Transitive Dependency)の存在 © GMO Flatt Security Inc. All Rights Reserved. 17 / 52
  12. axios 事例と LiteLLM 事例の比較からみるパターン axios (npm) LiteLLM (PyPI) 攻撃起点 メンテナへの

    S.E. CI からの PyPI トークン窃取 配布チャネル npm(正規レジストリ) PyPI(正規レジストリ) 発火トリガ postinstall script import 又は .pth autoload 除去までの時間 約3時間 同日中 入口のプレイブックもパターン化されつつあるように見える いずれも正規の配布チャネルが悪用され、普段と同じコマンドで感染する 発火トリガも、今のエコシステムのありようを踏まえると、完全に潰すことは難しい 検知は早かったもの、攻撃者側も自動化を進め、短時間で走っている。検知されないケースもあるだろう ▼ 「1メンテナを侵害して、広くインストールした人を短時間で叩く」のフローは今後も起こる 理由 2: 攻撃パターンは再利用可能 © GMO Flatt Security Inc. All Rights Reserved. 19 / 52
  13. 入口には CI 侵害・メンテナ直接リーチ・ワーム型の3類型が見られる 時期 パッケージ エコシステム 攻撃起点 2025/9~ Shai-Hulud (複数)

    npm ワームによる NPM_TOKEN 窃取 2026/1 dYdX npm + PyPI メンテナアカウント侵害 2026/3 Trivy GitHub Actions CI からの PAT 窃取 2026/3 LiteLLM PyPI CI からのトークン窃取 2026/3 Telnyx PyPI CI からのトークン窃取 2026/3 axios npm メンテナ端末のソーシャルエンジニアリング 理由 2 の補足: 入口プレイブックの類型 © GMO Flatt Security Inc. All Rights Reserved. 20 / 52
  14. AI にコードを書かせている場合、何を使っているか把握できているか 自分でコードを書いていないのに、 「このパッケージは使っていない」と断言できるだろうか # AI アシスタントが依存を追加する例 $ cursor "HTTP

    リクエストを送るコードを書いて" → npm install axios@latest # ← 公開直後でも疑わない → npm install plain-crypto-js # ← 名前が似ていても疑わない Copilot / Cursor / Claude Code 等が依存を選び、追加し、CI まで実行する時代になっている もともとパッケージ追加時に人間が判断していた。それが一定の防波堤だった AI はその判断をスキップする。公開直後のパッケージも、名前が紛らわしいパッケージも素通りする AI が名前をハルシネーションし、存在しないパッケージ名を生成する問題も報告されている(Slopsquatting) 攻撃者がその名前を先に登録すれば、AI 利用者が自動的にインストールする 理由 3: 「使っていない」と本当に言えるか? © GMO Flatt Security Inc. All Rights Reserved. 21 / 52
  15. npm の lifecycle script は install だけでコードを実行する axios 侵害で悪用されたのは、npm の

    postinstall スクリプト。他でも同様に悪用可能 $ npm install gatsby [email protected] └── [email protected] ← npm が自動的に解決した(あなたは選んでいない) postinstall: node setup.js ← npm が自動的に実行した npm はパッケージの postinstall スクリプトを install 時に自動実行する 推移的依存のスクリプトも実行される。gatsby を入れただけで axios の postinstall が走る 構造的には、これさえ無ければ、攻撃のステップは 1 つ増える(→ 攻撃者にとって面倒が増える) 実際、pnpm v10~ はこの挙動をデフォルトでブロックする方向に転じている 許可リスト( allowBuilds )に明示的に登録したパッケージのみ実行を許可する挙動をとる Bun も Top 500 パッケージの許可リスト + trustedDependencies で制御しているよう 構造 1: install 時のコード自動実行の仕組みがある © GMO Flatt Security Inc. All Rights Reserved. 23 / 52
  16. JavaScript 系パッケージマネージャごとの対応状況 マネージャ lifecycle script のデフォルト挙動 npm 全て実行。最もリスクが高く、最も広く使われている Yarn Classic

    (v1) 全て実行。npm と同様 Yarn Berry (v2+) 全て実行(定義上は false だが、互換性設定で true に上書きされている) pnpm v10+ デフォルトブロック。 pnpm approve-builds で許可リストを管理する Bun 許可リスト制。Top 500 パッケージ + trustedDependencies Yarn Berry はドキュメント上 enableScripts のデフォルトを false と記載している ただし互換性のためのマイグレーション設定(設定バージョン < 9)で true に上書きされており、現時点では全て実行される pnpm v10 のデフォルトブロック化は大きな転換点だった ただし pnpm approve-builds で承認を求められても、適切に判断できるかは別問題 pure JS のはずの axios が postinstall を要求していたら不審だと気づけるか? 多くの開発者は素通りしてしまうだろう esbuild のように正当に postinstall を必要とするパッケージは、そもそもブロックできない 構造 1: install 時のコード自動実行の仕組みがある © GMO Flatt Security Inc. All Rights Reserved. 24 / 52
  17. 他言語エコシステムとの比較(※ 補足: やや挙動自信ないです、米内も勉強中) エコシステム 仕組み install 時に動くか 制限手段 pip (Python)

    setup.py 動く(sdist) --only-binary :all: Cargo (Rust) build.rs ビルド時に動く 制限手段なし Go なし 動かない 設計上排除 Maven (Java) プラグイン実行 ビルド時に動く プラグイン構成次第 Composer (PHP) post-install-cmd 自プロジェクトのみ 依存パッケージの scripts は無視 Go は設計上、install 時のコード実行を一切許さない Composer は依存パッケージの script を実行しない設計(自プロジェクトの script のみ実行) pip は wheel(バイナリ配布)であればコード実行なし。sdist(ソース配布)のみリスクがある ただし require() や import された瞬間に動く検体は十分にある install 時の自動実行がなくても、コードが読み込まれれば発火する。狙いやすさが違うだけ LiteLLM の際の侵害内容はまさにこのパターン 構造 1: install 時のコード自動実行の仕組みがある © GMO Flatt Security Inc. All Rights Reserved. 25 / 52
  18. package.json への依存追加に稟議はない 「ソフトウェアを持ってきて使う」は割と軽率に行われている OSS は As-Is 提供であり、リスクが提供元と共有される SaaS 利用よりリスクフルとも言える にもかかわらず、依存の追加に対するガバナンスは多くの組織で未整備

    2021年ごろの EO 14028(大統領令)前後で、ようやく「何を使っているか把握せよ」が要請された程度 つまり業界はまだ把握の段階にいる。今必要なのは、検知・防御・対応であるが、ここに追いついていない 構造 2: 依存管理は牧歌的である © GMO Flatt Security Inc. All Rights Reserved. 26 / 52
  19. SBOM は「把握」の仕組みであり「運用」の仕組みではない 必要な統制 出荷時(ビルド時点) 開発中(日常) 構成要素の把握 SBOM でカバー SBOM では追えない

    脆弱性情報との突合・対応 SBOM + 脆弱性 DB で可能 リアルタイム性に欠ける 悪性パッケージの検知 カバーされない カバーされない インストールのブロック カバーされない カバーされない 侵害発覚後の即時対応 カバーされない カバーされない SBOM がカバーするのは「出荷時点で何が含まれていたか」の棚卸のみ axios は約3時間で除去された。SBOM の生成→交換→確認→対応のサイクルはこの速度に追いつかない SBOM は基礎的な「把握」として重要だが、運用速度の観点では、より能動的な仕組みが必要になる 構造 2: 依存管理は牧歌的である © GMO Flatt Security Inc. All Rights Reserved. 27 / 52
  20. 1メンテナの侵害が、数千万 DL/週のパッケージを掌握する ソフトウェアサプライチェーン攻撃は、攻撃者にとって極めてコストパフォーマンスが高い 指標 SaaS / サービスを直接狙う パッケージを狙う 初期投資 高い(対象ごとの調査・ゼロデイ等)

    中程度(メンテナへの S.E. 等) 到達範囲 1サービスの利用者 パッケージの全利用者が同時に影響 得られるもの 1組織のデータ / アクセス 大量のクレデンシャル + 次の侵害の起点 axios のメンテナ1人を侵害するだけで、週間1億DL・直接依存 174,000 パッケージの影響圏が手に入る 構造 3: 攻撃1回あたりの経済性が高い © GMO Flatt Security Inc. All Rights Reserved. 28 / 52
  21. 1回の侵害で得たクレデンシャルが、次の侵害の起点になる 1回の侵害で窃取したクレデンシャルが、次の侵害の起点になる 1回目 Trivy Action 474 リポジトリで 悪性コード実行 → 収穫

    クレデンシャル PyPI トークン npm トークン等 → 2回目 LiteLLM + Telnyx 悪性バージョンを PyPI に publish → さらに 1,705 パッケージ 推移的依存で 自動的に到達 1つの端末やシステムを侵害し、そこで得た認証情報で隣に移る。ラテラルムーブメントの構造そのもの 違いは、移動先が「隣のサーバ」ではなく「別の OSS パッケージ」であること GitGuardian は「数十万のシークレットが流通している可能性がある」と評価している(GitGuardian) Shai-Hulud 2.0 では侵害マシンの 20% が CI/CD ランナーだった(GitGuardian) CI/CD はクレデンシャルの宝庫であり、ラテラルムーブメントの「ハブ」になっている 構造 4: 事象がカスケードする © GMO Flatt Security Inc. All Rights Reserved. 29 / 52
  22. 戦略の方向性 利用・依存するソフトウェアに対して、以前より厳しい目線と仕組みを持つ必要がある 「package.json の中身」に稟議が必要な組織は少ないが、依存の追加は SaaS 購入と同質のリスクを持つ とはいえ使わないのは現実的ではない。使いながらどう守るかを考えるほかない 具体的には以下の四本柱で仕組みを強化されたい 柱 内容

    代表的な手法 (1) 受け入れ評価 利用するソフトウェアを厳しく評価する Dependency Cooldown、供給元キュレーション (2) 依存固定 mutable な参照を潰す SHA pinning、lockfile (3) アーキテクチャ堅牢化 侵害されても連鎖しない構造にする ビルド/デプロイ分離 (4) エンドポイント統制 CI/CD も端末と同じように守る CI/CD ログ、eBPF トレーシング どう備えるか © GMO Flatt Security Inc. All Rights Reserved. 31 / 52
  23. 大規模侵害事案を回避するために 大規模な侵害は誰かが気がつくので、 「新しいものは一旦受け入れない」は有効 3/24 LiteLLM 19:39 UTC に公開 → 同日中に

    PyPI が停止した 3/31 axios 00:21 UTC に公開 → 約3時間で npm が除去した 今日紹介したインシデントは、公開直後に飛びつかなければ巻き込まれにくかった例 この「すぐ入れない」を仕組みにするのが Dependency Cooldown の考え方 新バージョンが出てから一定期間、自動更新やインストールをブロックする その間にコミュニティの検知やレジストリの対応を待つ ただし、数日待てば安全かというと正直そうでもない 今回はたまたま早く検知されたが、影に隠れたまま長期間残っている検体は普通にある 単なる dropper であれば、検疫期間中は無害で、通過後に C2 から本体を落とすこともできる 受け入れ評価の強化 (1): Dependency Cooldown © GMO Flatt Security Inc. All Rights Reserved. 32 / 52
  24. 仕組みとしてどう実現するか 各クライアントに Cooldown 相当の仕組みが出てきている # npm v12+ npm install --min-release-age=3d

    # uv (Python) uv add --exclude-newer "3 days" <pkg-name> # GitHub Actions (pinact) pinact run --min-age 3 上述のように各マネージャに Dependency Cooldown 相当の仕組みがある。積極利用すべき 全てのクライアントが対応しているわけではない点が現状の課題 私見では 短くて 3 日、余裕をもって 7 日くらいあれば十分(体感、3日見つからない検体はしばらく見つからない) 受け入れ評価の強化 (1): Dependency Cooldown © GMO Flatt Security Inc. All Rights Reserved. 33 / 52
  25. 検疫期間だけでは足りないケースもある 理想論で言えば、そもそも「何を使うか」の判断自体を、もっと厳密にやるべき 評価指標 評価しやすさ 有効性 メンテナの数・権限構成 高い 一定有効 過去のインシデント履歴 高い

    一定有効 署名の有無・ビルド再現性 中程度 有効 推移的依存の供給元まで評価 非常に低い 理論上は有効 本質的に、推移的にどこまで信頼するかという問題になる 直接の依存は評価できても、その先は現実的に厳しい 直近事案が示すのは、1つの侵害が容易にカスケードすること 供給元評価をしていても、カスケードで簡単に詰みうる 受け入れ評価の強化 (2): 供給元の評価 © GMO Flatt Security Inc. All Rights Reserved. 34 / 52
  26. 一個一個は評価できないが、どこから拾ってくるかはある程度選べる 個別パッケージの評価が無理なら、信頼できるキュレーション層を挟む (2) で見たように、個別の供給元評価は transitive dependency の壁にぶつかる ただし「どこから拾ってくるか」はある程度選ぶことができる 検査やキュレーションを専門にやっている企業を経由するアプローチ コンテナイメージ:

    たとえば Chainguard Containers などは一手 最小構成のイメージを署名・SBOM 付きで提供している ベースイメージの選定をここに寄せるだけで、既知脆弱性の混入リスクが大幅に下がる ソースツリー自体が汚染されるシナリオを除けば、マルウェアの混入防止にも若干寄与する パッケージ: Takumi Guard がプロキシレイヤで機能する(後述) npm / PyPI のリクエスト経路に入り、ブロックリスト照合・検疫・侵害通知を提供する 個別パッケージの評価を利用者がやらなくても、プロキシ側で検査が走る 全員が評価に手を出すのは無理なので、こうした層に委ねる判断が現実的だと思う 受け入れ評価の強化 (3): 供給元の限定 © GMO Flatt Security Inc. All Rights Reserved. 35 / 52
  27. 受け入れ評価・検疫・依存固定を支援するプロダクト npm / PyPI のレジストリプロキシとして経路に入り、悪性パッケージをブロックする npm config set registry https://npm.flatt.tech/

    pip config set global.index-url https://pypi.flatt.tech/simple/ 1コマンドで導入できる。無料で利用できる npm / pnpm / pip / uv / poetry 等に対応 インストールリクエスト時にブロックリストを照合し、悪性ならば 403 でブロック メール登録するとレートリミット拡大(1万 req/分)+ 事後の侵害通知が届く 受け入れ評価の強化 (3): 供給元の限定 …の例としての Takumi Guard © GMO Flatt Security Inc. All Rights Reserved. 36 / 52
  28. 背景にある intel 活動 弊社のリサーチチームが運用する脅威インテリジェンス基盤でブロックリストを構築している 収集 レジストリ監視 npm / PyPI の

    変更フィードをリアルタイム監視 → 解析 自動解析パイプライン スクリプト検査 サンドボックス実行 → 判定 ブロックリスト反映 パッケージ全体または バージョン単位でブロック Takumi Guard はパッケージ公開を(ニア)リアルタイムで捕捉している 各パッケージレジストリにそのような仕組みがあり、それを利用 今後それができないレジストリの場合は、ダウンロード時に初見なら検査、となりうるが 各パッケージに関して、静的解析と動的解析を組み合わせて判定する パブリックアドバイザリが出る前にゼロデイの悪性パッケージを検出できる False Positive を極力避けるため、最終的に人間のアナリストも判定に関与(HITL) ブロックリストには日々レコードが追加されている 細かい解析方法は(話してしまうと攻撃者に手の内を明かすことにもなるため)非開示 Takumi Guard (2): ブロックリストの構成 © GMO Flatt Security Inc. All Rights Reserved. 37 / 52
  29. 後から悪性と判明した場合にどうなるか メールを登録しておくと、ダウンロード済みパッケージに侵害が判明した際に通知が届く # メール登録(無料) curl -X POST https://npm.flatt.tech/api/v1/tokens \ --json

    '{"email": "[email protected]", "language": "ja"}' # 返ってきたトークンを設定 npm config set //npm.flatt.tech/:_authToken tg_anon_xxxxxx メール登録すると、tarball のダウンロード履歴がトークン単位で記録される 後から悪性と判明した場合、該当バージョンをダウンロードした利用者にメール通知する パッケージ名・バージョン・ダウンロード日時・推奨される対応を含む GitHub Actions + OIDC 認証を設定済みの場合は、Webhook 等での通知を予定している Takumi Guard (3): 事後通知 © GMO Flatt Security Inc. All Rights Reserved. 38 / 52
  30. 対応範囲の拡大と解析の高度化 現在は npm / PyPI が対象。今後エコシステムと解析能力の両方を広げていく エコシステムの拡大(無料提供) RubyGems 対応 crates.io

    対応 … ダウンロードログ提供(有料・法人向けを予定) 「うちの CI であのバージョン使ってたっけ?」に実ダウンロードログで答えられるようにする lockfile からでは追うのが面倒で、誤判断もありうる。実ログベースで判断できるのは大きい 悪性パッケージの IoC の提供(有料・法人向けを予定) 具体的なマルウェアの挙動情報などを提供予定 キャンペーン事後対応や脅威インテリジェンスでの活用を想定 Takumi Guard (4): 今後の予定 © GMO Flatt Security Inc. All Rights Reserved. 39 / 52
  31. 評価済みのバージョンへの pinning を徹底する 入口で評価した安全とされるアーティファクトだけを参照・依存する # GitHub Actions: SHA pinning (mutable

    タグを使わない) uses: actions/[email protected] # v4.2.2 # npm: lockfile から再現性を担保 npm ci # pip: ハッシュ検証付きインストール pip install --require-hashes -r requirements.txt axios 侵害では ^1.14.0 が悪性パッチ 1.14.1 を引き込んだ。lockfile + npm ci なら防げた GitHub Actions なら SHA pinning。@v1 は侵害が即波及する 評価と固定はセットで考える 評価したものへの依存固定 © GMO Flatt Security Inc. All Rights Reserved. 40 / 52
  32. pinact: SHA pinning の自動化 手で SHA を調べて書き換えるのは現実的ではない。自動化ツールを使う # before -

    uses: actions/[email protected] # pinact を実行すると - uses: actions/[email protected] # v4.2.2 pinact はワークフロー内のタグ参照を自動でフルコミット SHA に変換する 入力と出力がシンプルで、大規模組織での自動化に向いている HACK THE NIKKEI BLOG の記事が参考になる 先述の --min-age オプションで Dependency Cooldown も同時に実現できる 評価したものへの依存固定 の例 © GMO Flatt Security Inc. All Rights Reserved. 41 / 52
  33. 即死構成を減らす。侵害されても連鎖しにくい構造にする たとえばデプロイとビルドの分離は堅牢化のための一つのアイデア 危険度: 高 ビルド 外部スクリプトが ガンガン動く場所 → 境界 アーティファクト

    ここだけが 両者の接点 ← 本番権限あり デプロイ 参照して設置するだけ 任意コード実行はしない ビルドは外部依存のコードがガンガン動く場所。ここに本番の鍵を渡すリスクは以前より高い npm install の Lifecycle script、 curl ... | sh のようなパターン、… 非自明だが git コマンドすら任意コード実行パスになりうる デプロイは根本的に本番への強い権限を持つので、極力ビルドと同居させないべきである 分離すれば、ビルド環境が侵害されても本番に直結しない アーティファクト汚染のリスクは残るが、アーティファクト汚してくる検体は比較的まだ少ない(増えてきたら要検討) アーティファクトだけが両者の接点になるような設計をイメージするといい DevOps 系アーキテクチャの堅牢化 © GMO Flatt Security Inc. All Rights Reserved. 42 / 52
  34. 端末を守るように CI/CD も守る 全部を防ぎきるのは無理筋でもある。一定やられた前提で追えるようにしておく 開発端末は EDR 等のエンドポイント監視が一定されている傾向有 一定の検知、一定の事後のレスポンスも(技術的には)できそうな環境が増えている 実際のところソフトウェアサプライチェーン系は、若干検知が後手になっている空気は感じるが、改善されていくと予想 プロダクト環境

    も一定の監視が進む GuardDuty(AWS)等、マネージド・低ハードルの製品も一定存在している 性能の面ではまだ完璧ではないが、一定の監視は行えるようになっている CI/CD 環境 は現在間隙で、かなりログ・テレメトリすらない傾向にある マネージドの GitHub Actions 環境は特にその傾向が強い Trivy の件も LiteLLM の件も、野良の npm マルウェアも、後からレスポンスするのはほぼ困難 ▼ CI/CD 環境のログ・テレメトリ確保は 2026 年意識すべきテーマ DevOps 系エンドポイント統制の強化 © GMO Flatt Security Inc. All Rights Reserved. 43 / 52
  35. eBPF トレーシング付きの GitHub Actions Runner runs-on: takumi-runner の1行で、ワークフロー実行中のすべてを記録する GitHub Actions

    の Runner として動作する ジョブごとに専用のエフェメラル VM を起動する 独立したカーネル・ファイルシステム・ネットワークスタックを持つ コンテナ型と違い、カーネルを共有しないので分離が強い eBPF でシステムコールレベルのトレースを取る process_exec / net_connect / file_open 等 「どのプロセスがどこに通信したか」が全部見える 「どのプロセスがどんなファイルを読み書きしたか」も全部見える 取得したトレースデータは DuckDB クエリで分析できる ログの生 JSONL 自体も提供可能 これにより有事のインシデントレスポンスが可能に Takumi Runner (1): CI/CD 環境の記録・監視 © GMO Flatt Security Inc. All Rights Reserved. 44 / 52
  36. 仮に axios の侵害バージョンを CI で使っていたら 侵害バージョンが C2 に通信していれば、ネットワーク可視化に即座に現れる 仮に自社の CI

    で侵害済み [email protected] を使っていた場合を考える sfrclak[.]com:8000 への通信がトレースに記録されていた 侵害が公表された時点で過去のジョブを IoC ベースで検索できる うち影響あった?はこれにより(ほぼ)確定させられる eBPF トレース自体の完全性が確保される限りは確定する 完全性が確保されないようなシナリオでは、そもそも何かがおかしい Takumi Runner (3): ネットワークテレメトリの利用 © GMO Flatt Security Inc. All Rights Reserved. 46 / 52
  37. Detection に加え、Prevention・Hunting へ 記録と検知だけでなく、攻撃の成立自体を防ぎ、能動的に発見する方向へ広げていく Prevention: Rootless mode reviewdog / Trivy

    いずれの事案でも /proc/<pid>/mem 経由のメモリダンプが使われた Hosted Runner では root を取れるので、Runner.Worker のメモリを読み出せてしまう Rootless mode では Runner プロセスを非 root で実行し、メモリ読み出しを防ぐ エフェメラル VM で分離しても root が取れる限り攻撃は成立する。ここを根本的に塞ぐ Hunting: トレースデータの能動的活用 蓄積されたトレースデータに対して、既知の攻撃パターンを遡及的に検索する 新しいアドバイザリが出た時点で、過去のジョブに同じ痕跡がなかったかを調査できる 直近の大規模侵害時(Trivy 等)のレスポンス支援もここに含めていきたい Detection は「リアルタイムで気づく」 、Hunting は「後から能動的に見つけに行く」 Takumi Runner (6): 今後の展望 © GMO Flatt Security Inc. All Rights Reserved. 49 / 52
  38. みなさんが「次の被害者」になりうる。前より厳しい目で統制し、この乱世を生き延びましょう 第1部 何が起きたか axios のメンテナ1人が侵害され、週間1億DLのパッケージから RAT が配布された 約3時間で除去されたが、その間に install した環境は影響を受けた

    第2部 なぜ「不使用だからOK」ではないのか 推移的依存で誰もが到達圏内にいる 攻撃パターンは再利用される。次は別のパッケージで起きる AI にコードを任せる時代に、何を使っているか把握できているか 第3部 なぜ侵害は繰り返されるのか install 時の自動実行、牧歌的な依存管理、攻撃の経済性、カスケード、… 第4部 対策: Consumer として Dependency Cooldown・依存固定・アーキテクチャ堅牢化・DevOps系エンドポイント統制、… さいごに © GMO Flatt Security Inc. All Rights Reserved. 51 / 52