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
250
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
240
ソースコード→AST→オペコード、の旅を覗いてみる
o0h
PRO
1
180
PCOVから学ぶコードカバレッジ #phpcon_odawara
o0h
PRO
0
370
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
250
夢の無限スパゲッティ製造機 #phperkaigi
o0h
PRO
0
900
PHPer Book Revue 「雑に作る」 #phperkaigi
o0h
PRO
0
380
俺にも私がAIと作った オススメの個人ツールを語らせてくれ
o0h
PRO
0
76
#phperbiglt のLT
o0h
PRO
0
110
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
280
Other Decks in Programming
See All in Programming
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
550
New "Type" system on PicoRuby
pocke
1
930
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
230
Vite+ Unified Toolchain for the Web
naokihaba
0
310
Oxlintのカスタムルールの現況
syumai
6
1.1k
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.6k
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
690
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
130
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
11
4.1k
CSC307 Lecture 17
javiergs
PRO
0
320
AIで効率化できた業務・日常
ochtum
0
130
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
140
Featured
See All Featured
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
210
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.1k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
160
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
440
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
380
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