Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
Search
hideki kinjyo
PRO
May 28, 2026
Programming
240
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
PHP勉強会@東京 第187回の発表資料です。
https://phpstudy.connpass.com/event/391794/
hideki kinjyo
PRO
May 28, 2026
More Decks by hideki kinjyo
See All by hideki kinjyo
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
210
ソースコード→AST→オペコード、の旅を覗いてみる
o0h
PRO
1
170
PCOVから学ぶコードカバレッジ #phpcon_odawara
o0h
PRO
0
370
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
240
夢の無限スパゲッティ製造機 #phperkaigi
o0h
PRO
0
490
PHPer Book Revue 「雑に作る」 #phperkaigi
o0h
PRO
0
380
俺にも私がAIと作った オススメの個人ツールを語らせてくれ
o0h
PRO
0
74
#phperbiglt のLT
o0h
PRO
0
110
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
280
Other Decks in Programming
See All in Programming
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
180
JavaDoc 再入門
nagise
0
300
ふつうのFeature Flag実践入門
irof
7
3.6k
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
100
Oxcを導入して開発体験が向上した話
yug1224
4
290
These Five Tricks Can Make Your Apps Greener, Cheaper, & Nicer
hollycummins
0
280
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
200
AutonomyとControlのあいだ:Graflowで記述するAIエージェント協調
myui
0
110
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
550
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
Agentic UI
manfredsteyer
PRO
0
120
Webフレームワークの ベンチマークについて
yusukebe
0
150
Featured
See All Featured
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
180
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
560
Java REST API Framework Comparison - PWX 2021
mraible
34
9.3k
Mind Mapping
helmedeiros
PRO
1
240
The Limits of Empathy - UXLibs8
cassininazir
1
350
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
530
Odyssey Design
rkendrick25
PRO
2
690
Side Projects
sachag
455
43k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Into the Great Unknown - MozCon
thekraken
41
2.6k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Transcript
Composerを使った サプライチェーン攻撃の様子を 眺めてみる 第187回 PHP勉強会@東京 Hideki Kinjyo GitHub: o0h /
X: @o0h_ [公開用]
※発表後の追記
以下、発表内容
Composerを使った サプライチェーン攻撃の様子を 眺めてみる 第187回 PHP勉強会@東京 Hideki Kinjyo GitHub: o0h /
X: @o0h_ [公開用]
今日の登場人物 Composer パッケージ入れる君 Packagist パッケージ情報を 教えてくれるさん (電話帳的な?)
自己紹介 • 金城秀樹 / きんじょうひでき • GitHub: @o0h / 𝕏
: @o0h_ • アイコンは美味しい鮭親子丼の写真です • 来週の今頃は札幌にいます • 最近はPodcastをやっています • ハッシュタグ: #readlinefm
今日の話 ここのところ、 毎週くらいのペースで 脆弱性やサプライチェーン攻撃の話を 聞くじゃんね〜〜〜〜〜〜
今日の話 Composer界隈の皆さんと、 「それってどうやって起こるの??」を 見ていきたい!!
今日の話 という話です
(裏?ばなし) きっと、今日より踏み込んだ(?)話は PHP Conference Japanで 誰かから聴けるでしょう!! 気になるプロポーザルに ★を付けて盛り上げよう💪 https://fortee.jp/phpcon-2026/
proposal/all?q=サプライチェーン&f=all
話すこと • Composer+Packagistにおけるサプライチェーンアタックについて • 汚染/侵害されたサードパーティパッケージが混入してくる、 というケースのみに限定します • ソフトウェアサプライチェーンアタックはもっと色々ある
話さないこと ↓は話さない • サプライチェーンアタック一般への(専門的)な対策方法 • 今回は「Composerの場合」を追うのが主なので 一般的な話は、そういう文献等を当たってください
おしながき 1. その攻撃は、どういう風に実行されるの 2. その攻撃は、どういう風に入り込むの 3. 昨今のComposer側の対策
参考記事(日本語) • 前に書いた: 『昨今のComposerは(サプライチェーンアタックについて)どうなって るんすかね??って軽く調べ - 大好き!にちようび』 https://daisuki.nichiyoubi.land/entry/2026/04/03/005936 • あと、コドモンさんの記事:
『できることから始めるPHPプロジェクトのOSSサプライチェーン攻撃 対策 - コドモン Product Team Blog』 https://tech.codmon.com/entry/2026/04/27/092802 • 自分が勢いで書いたコンテンツより、整ってるんじゃないですかねぇ
その攻撃は、どういう風に実行されるの
そもそも超大前提的な 開発者(パッケージのユーザー)が 意図しないタイミングで 変な動きをする!!! ・・・が困る、って話
例えるなら "何もしていなのに" 感 インストールしただけなのに コードいじってないのに 手順を守った(or自動化された) やり方なのに
(怖い)デモ: いつも通りの`composer install`を ぶっ壊します
None
None
None
None
怖いですね いつもの`composer install`が、 いつもと全然違う挙動
怖いですね これは「文字列をechoする」だけだが、 「何かを出来ている」状態にありますね?
怖いですね 「ざまぁ〜」する代わりに、 「本番用のビルドにおいてAWSのクレデンシャルやSSH キーを環境変数etcから抜いてどっかにPOST」でも 良いわけです
Composerにおいて 「自動的にコードを動かせる」のは、どこ?
自動実行を差し込める所 1. プラグインとして動作して、任意のイベントで発火 ➡ installなど、Composerコマンドの実行時 2. オートロード(イーガーロード)ファイルとして動作させる ➡ Webリクエストやバッチ実行時など、`autoload.php`読込み時
Pluginでの実行
Composerのプラグインの仕組み • Composerは、そのコマンド実行時に ライフサイクルに応じたイベントを発行している • プラグインは、そのイベントを購読して、独自処理を発火する仕 組み 主なイベントの例: composer.lockの更新完了時・パッケージのDL時・autoloadファイルの生成時etc
例えばこんなプラグイン • cweagans/composer-patches • パッケージインストール後、vendorファイルに任意のパッチを当てる • php-http/discovery • 依存更新(composer.lock更新)時に、 「対象HTTPクライアントが何かしら入っているか」をチェックする
さっきのデモの中身
autoloadでの実行
何の変哲もない 四則演算プログラム
あやしいパッケージを 入れて・・
あやしいパッケージを 入れて・・
ただ普通に プログラムを実行
汚染
汚染
何をされているのか • Composerに「オートロード」ありますよね • 「PSR-4」とかのやつです • ↑の場合、composer.jsonにnamespaceと対応ディレクトリを指定する • オートロードの種別に `files`
というものがあります • これは「クラス(like)定義」以外に使います • 有名どころで言うと、symfony/polyfillとかがメッチャ使う • 指定されたファイルが自動で読み込まれるようになる • PSR-4などは、「遅延読み込み」のための仕組み
さっきのデモの中身: パッケージ定義
さっきのデモの中身: 核心のコード src/bootstrap.php
さっきのデモの中身: autoloadfiles vendor/autoload.php から 読み込まれているファイル
さっきのデモの中身: autoloadfiles vendor/autoload.php から 読み込まれているファイル
さっきのデモの中身: autoloadfiles vendor/autoload.php から 読み込まれているファイル
要するに
Composer利用時に気をつけたいこと • Pluginは比較的自由が効くので、安易に使わない • Composerが提供している安全機構については後述 • autoload.filesは・・・厄介ですねぇ • 使うべきでない、というのもちょっと現実的ではない •
気をつけることは出来るかもだけど • 両者で、発火タイミングが違う
その攻撃は、どういう風に入り込むの
まずは Composer/Packagistの情報管理
レジストリ利用者としてのComposer • 今回はデフォルトレポジトリ = Packagistの話に限定しますが • Packagist自体は、パッケージの実コードやバイナリを持たない • パッケージの本体は、(主に)GitHubを案内している •
代わりに、メタ情報だけを管理している • 提供しているパッケージ名と、バージョンの情報 • 各バージョンに対応するハッシュ(Gitコミットハッシュ)
composer.json (基本的には) 利用したいバージョンの 「範囲」を指定する
composer.lock
composer.lock バージョンが 明示的に指定され
composer.lock 実コードの 取得先が示される
パッケージ情報のソース • この辺りの「バージョンとかハッシュとかdistのURL」を 届けてくれているのが、PackagistのAPI • https://repo.packagist.org/p2/***/***.json • Composerはコレを参照して、取り込んでいる
package.json めっちゃ割愛した 情報
package.json バージョンごとに distが入る
ヤバいコードはどうやってくるか
composer.lockがない場合 • composer.lockがない(もしくは更新される)場合、 「(制約を満たす範囲で)何が入ってくるかが保証されない」。 • 更新される場合? • composer update •
composer require
composer.jsonで「具体的な指定」をしていても? • 例えば、`composer require cakephp/cakephp:5.4.0` を指定 • ・・・しても、中身が同じ事は保証されていない • Packagistの場合、同じリリース(タグ)での更新が可能
• force push出来ちゃう
とても分かりやすい話
先日のlaravel-langのやつ • Laravel Lang Compromised with RCE Backdoor Across 700+
Versions https://socket.dev/blog/laravel-lang-compromise • 権限を取られた(断定してないかも)様子がある • 攻撃者が、org内のコード等を操れる状態に • CIの履歴を見ると、生々しく現場の様子が残ってる
None
過去のタグが (再)pushされている・・
CIのジョブに紐づいているコミット
CIのジョブに紐づいているコミット イーガーロードに 追加されている
こうなると、どうなる? • 「正当だったバージョン」の内容は書き換えられて 「違うコミットハッシュ」になっている • composer.lockが変わっていなければ、 「いま汚染されたファイル」を食わされないで済む • 一方で、composer require/update系の
composer.lockの更新は、汚染されたバージョンを食う
昨今のComposer側の対策
Plugin周り
プラグインは「明示的に許可されたもの」のみ動く • Composerでは、プラグインは予め許可したものしか実行されない • 2.2.0〜 (2021年リリース) • 許可できるのは、PJのrootにある `composer.json`のみ •
つまり、require/updateで入ったパッケージからは使えない
マルウェアフィルター
汚染されたバージョンのブロック • https://github.com/composer/composer/pull/12766 • 次のバージョン(2.10)から • Packagist側が、「汚染されたバージョン」フラグを提供する これをみて、危ないものが入りにくいようブロックする • Aikido
Securityによる提供
flagged as malware by Aikido
flagged as malware by Aikido
laravel-langはこんな感じ
None
ナイスブロック👏
ナイスブロック👏
(安定版)バージョンの上書き不可に
リリースされたタグは上書きできなくなる • Packagist側の修正 • 1度リリースされたバージョンは、 内容が同一であるものと保証しやすくなる • 5/28(JST)時点で、まだマージされていない • https://github.com/composer/packagist/pull/1742
• ブログでは「in this week」のリリースと書かれている
その他の動き
Transparency Log https://packagist.org/transparency-log?actor=&user=&vendor=laravel-lang&package=&datetime_from=&datetime_to=2026-05-23T05%3A06%3A32
Transparency Log https://packagist.org/transparency-log?actor=&user=&vendor=laravel-lang&package=&datetime_from=&datetime_to=2026-05-23T05%3A06%3A32
予定されているもの・関心が寄せられているもの • (5/27) An Update on Composer & Packagist Supply
Chain Security https://blog.packagist.com/an-update-on-composer-packagist- supply-chain-security/ • Coming in the next weeks and months: • Minimum-release-age / cooldown • Longer-term direction: • Mandatory MFA across Packagist.org • Packagist.org hosting immutable build artifacts directly w/SLSA build provenance, Sigstore attestation
予定されているもの・関心が寄せられているもの • (5/27) An Update on Composer & Packagist Supply
Chain Security https://blog.packagist.com/an-update-on-composer-packagist- supply-chain-security/ • Coming in the next weeks and months: • Minimum-release-age / cooldown • Longer-term direction: • Mandatory MFA across Packagist.org • Packagist.org hosting immutable build artifacts directly w/SLSA build provenance, Sigstore attestation 補足: 現状、Packagistで配布するメタ情報にある`time`フィールドは、 パッケージの作者が任意に書き換え可能なので信頼しちゃ駄目
まとめ/今できること
「何が入っているか分からない」を防ぐ • ちゃんと.lockファイルを使いましょう • なるべく使うプラグインは減らしておいた方が良いかも • require-dev系でプラグインを使いたい時は、本番環境から隔離する • 本番には--no-dev インストールを使う
• vendor-binプラグインの活用 & 利用環境を分ける • CIで`composer audit` を定期実行するのも
「何が入っているか分からない」を防ぐ • Lockファイルの差分もPR単位で見るAction • https://github.com/marketplace/actions/composer-lock-diff • ただ、今の時代なら、 このくらいの軽量なものであれば自作しても良いかも • プラグインやGitHub
Actionsを増やしまくるのに不安がある場合
Composer 2.10を待ちましょう、飛びつきましょう • マルウェアブロック🙌 • 今週リリースらしい
ComposerとPackagistを支えよう https://github.com/sponsors/composer
おしまい! お付き合いいただき ありがとうございました!!
オマケ
auditfix的なコマンド
なに? • npmとかには `audit fix` 的なコマンドがあるらしいと聞いた • Composerでも、 「パッチを当てる最小限の変更」ができたら良いのにねぇ
現状確認
問題アリなver.
auditも見てみると
検出されている
検出されている
minimal-changesだと
変更無し
通常のupdate
結構versionが変わった
コレをどうにかしたい
PoC的なものを作ってみた
audit-fix
None
None
結果を見てみる
None
None
参考資料とか
過去に出した資料 • Composerのメタ情報収集の流れについて • Composer 2.0って何? どう変わるの? 読んでみました! (2020) https://speakerdeck.com/o0h/lets-read-composer2
• 作って理解するComposer <クイックコース> (2024) https://zenn.dev/o0h/books/phpcon-2024-composer-ws • プラグインの仕組みについて • 作って遊ぼう!Composer Plugin (2022) https://speakerdeck.com/o0h/phperkaigi-2022-composer-plugin-b
他のめっちゃ良い情報 • Jxckさんの記事。必読 • サプライチェーン攻撃への防御策 | blog.jxck.io https://blog.jxck.io/entries/2025-09-20/mitigate-risk-of-oss- dependencies.html •
GMO Flatt Security CTO米内さんの記事。パッケージマネージャーの比較も • axios, LiteLLM...不使用だったのでOK、ではない。「次に備える」ソフトウェア サプライチェーン侵害への対策 - Speaker Deck https://speakerdeck.com/flatt_security/axios-litellm-dot-dot-dot-bu-shi- yong-datutanodeok-dehanai-ci-nibei-eru-sohutoueasapuraitienqin-hai- henodui-ce