背景
ある日深夜、PHPコアに関する重大な脆弱性(CVE-2026-109618, CVE-2026-109619/リモートコード実行の恐れあり)が公開されました。
対象環境は CentOS 7(2014年7月リリース、2024年6月末サポート終了)+ PHP 5.6 という、典型的な「塩漬けレガシー環境」。
OS自体が既にEOLのため、yumでの公式パッチ配布も当然ありません。この記事は、そんな環境でどう脆弱性に向き合ったかの記録です。
Before / After
| 項目 | Before | After |
|---|---|---|
| Web実行PHP | PHP 5.6.32(mod_php、脆弱) | PHP 8.3.36(FPM、修正済み) |
| CLI/バッチ実行PHP | PHP 5.6.32 | PHP 8.3.36 |
| 導入方法 | OS標準パッケージ | 公式ソースから手動ビルド |
| 脆弱性 | CVE-2026-109618/109619 該当 | 解消 |
| フレームワーク | CodeIgniter 2.2.0(PHP5前提のレガシーコード) | 同一コードベースをPHP8.3で動作するよう修正 |
なぜPHP 8.3.36を選んだか
このOS(CentOS7)向けのRemiリポジトリでは、PHP 8.3系は 8.3.8 までしかビルドが存在しません。CentOS7のEOLと時期が重なったタイミングで、Remi側もこのOS向けのビルドを打ち切ったようです。つまり yumで入る範囲では、そもそも今回のCVEを修正したバージョンが存在しない 状態でした。
一方で、このアプリケーション自体は長年 8.3系 の挙動を前提に作られた部分もあり、メジャーバージョンを跳ばす(8.4や9.0へ一気に上げる)のは互換性検証コストが大きすぎると判断。そのため:
- 修正版が存在する最新の 8.3系パッチバージョン = 8.3.36 を選定
- 公式tarballのSHA256を検証した上で、ソースから直接ビルド
- OpenSSL 1.1.1(EPELのopenssl11)、devtoolset-11(gcc 11)など、OS標準より新しいビルド依存関係を別途揃えて対応
という方針を取りました。
PHP8.3移行で実際に発生した互換性問題
CodeIgniter 2.2.0 自体は2014年当時のPHP5.x前提のフレームワークのため、切り替え直後にいくつか実際に本番で踏んだ問題がありました。主なもの:
1. 動的プロパティの廃止警告(PHP8.2+)
class CI_Controller {
// $this->load, $this->db などを宣言なしに動的に生成する設計
}
PHP8.2以降は Deprecated: Creation of dynamic property が大量発生。フレームワークのコアクラス全体に #[AllowDynamicProperties] 属性を付与して解消しました。
#[AllowDynamicProperties]
class CI_Controller { ... }
この属性は #[...] というコメント風の記法なので、PHP5.6側で読んでも単なるコメントとして無視されるため、互換性を壊さず両対応できたのがポイントです。
2. 中括弧による配列/プロパティアクセス構文の完全廃止(PHP8.0)
// PHP8では構文エラーで即死
$this->_compile_{$section} = TRUE;
// 修正後
$this->{'_compile_'.$section} = TRUE;
3. mysqli_num_rows() の型厳格化(PHP8.1+)
USE database_name のようなDMLでない文を is_write_type() が検知できず、mysqli_query() が返す true(真偽値)をそのまま mysqli_num_rows() に渡してTypeErrorで死ぬケースがありました。DBドライバ側に「結果がbooleanなら結果オブジェクトを作らずそのまま返す」ガードを追加して解決。
4. サードパーティXMLパーサのエッジケース
現場からのXMLデータに特定条件で空配列が返るケースがあり、array_keys(null) のTypeErrorが連続発生。呼び出し元に ?? array() でnull安全化のガードを一括追加しました。
まとめ
- OSのEOLにより「公式パッケージでの脆弱性修正」という選択肢自体が存在しない状況だった
- そのため、ソースビルドという普段より手間のかかる方法を選択せざるを得なかった
- 2014年設計のレガシーフレームワークでも、動的プロパティ属性やnull安全演算子などPHP8側の互換性機能をうまく使えば、大規模な書き換えなしに移行は可能
- とはいえ根本的にはOS自体のアップグレードが必須であり、今回の対応はあくまで延命措置という認識
同じようにレガシーOS + レガシーPHPで塩漬けになっている環境の方の参考になれば幸いです。