0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CentOS7 + PHP5.6環境でPHPコア脆弱性(CVE-2026-109618/109619)に対応した話

0
Posted at

背景

ある日深夜、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で塩漬けになっている環境の方の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?