Skip to main content

PHP 8.2.33リリース対応 PHPセキュリティ保守サービス パッチ配布開始

ESIのPHPセキュリティ保守サービス(PHP 5.3〜8.1対応)では既知のセキュリティ問題を修正した古いバージョンのPHPをご利用頂けます。PHPプロジェクトによるPHP 8.1のメンテナンス期間は2025年12月のリリースで終了しました。今後、PHP 8.1以下の利用を継続されるには既知のセキュリティ問題を修正したPHPを利用する必要があります。

※ PHP 5.3のサポートを再開しました。

 

30 Jul 2026, PHP 8.2.33

=================================================================================
- Streams:
 . HTTPヘッダー行の解釈をRFC 7230準拠に統一。新しいINI設定
   http_header_parse_strict を追加(既定値 On)。

■ HTTPヘッダーの改行解釈の不一致によるレスポンス分割・リクエスト分割

■ 影響バージョン
PHP 5.3以降(http:// ストリームラッパーを持つ全てのPHP)

■ 互換性問題
あり。詳細は「■ 互換性への影響」を参照してください。
従来の挙動に戻すには php.ini で http_header_parse_strict = Off を設定してください。

本項目は 24 Sep 2026 に追加しました。本修正は、20 Sep 2026のお知らせ(RELEASE-NOTES-20260920.txt)
でご案内した修正に、その後の検証で見つかった不具合の修正を加えたものです。本リリースに含まれる
内容の全体を以下に記載します。

Upstreamの現行バージョンにはHTTPヘッダーをRFC通りに処理せず、HTTPレスポンス分割の原因と
なる曖昧な行末解釈が取り入れられています。レガシー版の方が厳しい(正しい)解釈をしようと
していますが、レガシー版の処理も正確ではありません。このパッチは厳格にRFC通りにヘッダー
処理をするモードと脆弱なPHPスクリプトも許容するモードをINI設定で変更可能にします。

■ 解説
ヘッダー行の区切りが何であるかの解釈が食い違うと、同じバイト列を一方は1つのヘッダー、
もう一方は2つのヘッダーとして読みます。この食い違いこそがHTTPレスポンス分割・リクエスト
分割の本体です。

PHPのhttp://ストリームラッパー内には、この解釈が4通り併存していました。

 ・ユーザー指定ヘッダーの重複検査        CRLFのみを区切りとする
 ・リダイレクト時のヘッダー削除          裸のLFも区切りとする
 ・CONNECT要求のProxy-Authorization抽出  先頭の空白を読み飛ばし、CR単独も区切りとする
 ・レスポンスヘッダーの読み取り          LFで分割する

このうちProxy-Authorizationの扱いでは実際に資格情報が漏れていました。
array("X: 1", " Proxy-Authorization: Basic ...") のようにヘッダーを渡すと、抽出側は
先頭の空白を飛ばしてこれをヘッダーと認識しプロキシへ転送する一方、削除側はヘッダー行と
見なさない為、同じ資格情報がトンネル内で接続先サーバーへも送信されていました。
また、トンネル内の接続先サーバーへ送るヘッダーからProxy-Authorizationを削除する処理は
最初の1行しか削除しておらず、2行指定すると2行目が接続先サーバーへ送信されていました。
本修正では該当する行を全て削除します。

本修正では、ヘッダー行の開始位置と終了位置を判定する処理を全て共通化し、その判定規則を
INI設定で選べるようにしました。

 http_header_parse_strict = On(既定値)
   RFC 7230の規定どおり、ヘッダー行の終端はCRLFのみとします。空白やタブで始まる行は
   直前のヘッダーの継続行であり、新しいヘッダー行ではありません。

 http_header_parse_strict = Off
   従来の緩い解釈に戻します。裸のLFも行の終端として扱います。ヘッダーの削除処理は、
   CONNECT要求のProxy-Authorization抽出と判定を揃える為、単独のCRも行の終端として扱い、
   行頭の空白やタブも読み飛ばします。

この設定は送信と受信の両方向に適用されます。

 送信  ストリームコンテキストの "header"、"user_agent"、"method" オプション、
       user_agent/from のINI設定、URL由来のパス・クエリ・ホスト
 受信  レスポンスのステータス行と各ヘッダー行、1xx応答(100 Continue等)の各行、
       プロキシのCONNECT応答の各行

On では、解釈が一意に定まらない値の送信自体を拒否します。半端に解釈して送信すると、PHPが
「そのヘッダーは無い」と判断して自前のヘッダーを追加する一方、サーバーは利用者指定の
ヘッダーを見る、という食い違いが生じる為です。特に空行は、サーバーにとってヘッダー部の
終わりを意味する為、それ以降がボディや2つ目のリクエストとして解釈されます。

 拒否される例(いずれも On のとき)
   ・裸のCRまたはLFを含む "header" オプション
   ・途中に空行を含む "header" オプション(下記の配列指定の説明も参照してください)
   ・フィールド名とコロンを持たない行
   ・空白やタブで始まる2行目以降の行(値全体の先頭の空白は取り除いてから検査します)
   ・CRやLFを含む "user_agent"、"method" オプション、user_agent/from のINI設定、
     URL由来のパス・クエリ・ホスト

 拒否した場合、fopen()やfile_get_contents()等は失敗し、次の警告を出力します。

   HTTP invalid "<オプション名>" context option (<理由>); header lines must be
   terminated by CRLF, or set http_header_parse_strict=0

 この検査は要求を送信する前に行う為、通常は何も送信されません。

 ストリームの通知コールバックは接続後に呼ばれる為、検査の後で "header"、"method"、
 "user_agent" オプションや user_agent/from のINI設定を書き換えることができます。これらは、
 要求に書き込む直前にもう一度検査します。この場合、次のものは既に送信されています。
   ・プロキシ経由のHTTPS接続では、検査済みのCONNECT要求
   ・PHP 5.3~5.5では、要求を組み立てながら送信する為、書き換えられた値より前の部分
     (要求行等)。"method"、"user_agent"、user_agent/from は、要求の最初の送信の前にも
     検査する為、接続時の通知で書き換えられた場合は何も送信しません。
 いずれの場合も、CRやLFを含む値そのものは送信しません。

 "header" オプションを配列で指定した場合は、実際に送信される形、つまり各要素をCRLFで
 結合し、前後の空白と改行を除いたものを検査します。その為、空の要素や、末尾に既にCRLFを
 付けた要素の後ろに空でない要素が続く場合は、結合すると途中に空行ができる為、拒否されます
 (空の要素は、前にも空でない要素がある場合)。先頭や末尾にだけある空の要素やCRLFは、
 前後の空白と改行を除く処理で取り除かれる為、拒否されません。

 include/requireでURLを読み込む場合(allow_url_include=On)はストリームコンテキストが
 ありませんが、user_agent/from のINI設定とURL由来の値は同じく検査します。

受信側では、On のとき次のように読み取ります。

 ・ステータス行とヘッダー行はCRLFで終端されていなければなりません。行内に単独のCRを
   含む行も拒否します。
 ・ステータス行は最初に128バイトの領域へ読み込みます。長いステータス行もCRLFで終端されて
   いれば受け付けます。CRとLFがこの領域の境目で分かれた場合も、正しいCRLFとして扱います。
 ・1xx応答(100 Continue等)の後は、各行を丸ごと読んで検査します。1xx応答のヘッダー部は
   空行で終わり、その次の行がステータス行でなければなりません。1xx応答のヘッダー部の中に
   ステータス行のような行がある場合は拒否します。1xx応答が続く場合(100 Continueの後の
   103 Early Hints等)も、それぞれ同じように検査します。
   PHP 5.3には1xx応答を読み飛ばす処理が無く、1xx応答をそのまま最終の応答として扱う為、
   この検査はありません。
 ・プロキシのCONNECT応答の各行は、長さに関係なく丸ごと読んで検査します。

■ 互換性への影響

1. ヘッダーを裸のLFで区切っているアプリケーション

  ストリームコンテキストの "header" オプションを "A: 1\nB: 2" のように裸のLFで
  区切っている場合、既定値 On ではリクエストが失敗します。CRLFに修正するか、
  http_header_parse_strict = Off を設定してください。

2. "header" オプションの配列の要素にCRLFを付けているアプリケーション

  array("A: 1\r\n", "B: 2") のように、最後以外の要素の末尾にCRLFを付けている場合、
  既定値 On ではリクエストが失敗します。要素を結合すると "A: 1\r\n\r\nB: 2" となり、
  途中に空行ができる為です。

  修正前もこの形では、B: 2 はヘッダーとして送信されていませんでした。サーバーは空行で
  ヘッダー部が終わったと解釈する為、B: 2 はボディの一部として扱われます。On ではこれを
  黙って送信する代わりにエラーとします。要素の末尾のCRLFを取り除いてください。

3. 裸のLFでヘッダーを返すサーバーとの通信

  レスポンスのステータス行やヘッダー行が裸のLFで終端されている場合、既定値 On では
  レスポンスを不正として拒否します。行内に単独のCRを含む場合も同様です。
  1xx応答の各行、プロキシのCONNECT応答の各行も同じです。該当するサーバーやプロキシと
  通信する必要がある場合は Off を設定してください。

4. 重複検査は両モードで厳格です

  利用者が既にヘッダーを指定しているかどうかの検査(Content-Type、Content-Length、
  Host、Authorization、Connection等)は、Off にしても緩和されません。これを緩和する
  ことはGHSA-hgf5-96fm-v528(CVE-2025-1736)の修正を元に戻すことと同義である為です。
  その結果、裸のLFで区切っているアプリケーションでは、Off にしてもPHPが生成した同名
  ヘッダーが重ねて送出されます。恒久的な対処はCRLFへの修正です。

5. リダイレクト時のヘッダー削除の範囲

  リダイレクトでPOSTがGETに変わる際、PHPは利用者指定のContent-Type、Content-Lengthを
  削除します。従来は、ヘッダー名を最初に見つけた位置が行頭でないと、そこで探すのを止めて
  いました。その為、"X-Note: content-type: a\r\nContent-Type: b" のように、値の中に
  同じ名前を含むヘッダーが先にあると、後ろの本物のContent-Typeが削除されずに残っていました。
  修正後は行頭で一致する行を探し続ける為、この場合もContent-Typeを削除します。削除する
  方向への変更であり、安全側の変更です。両モード共通です。

6. 長いステータス行(PHP 5.3~5.5、7.1~7.4)

  これらのバージョンでは、ステータス行が125文字以上になると、残りの部分をヘッダー行として
  読んでしまい、ヘッダーがボディに混ざったり、"no colon in header line" のエラーで失敗
  したりしていました。上流のGH-9316の修正を取り込み、長いステータス行の残りを読み捨てる
  ようにしています(PHP 5.6、7.0、8.0、8.1には取り込み済みでした)。両モード共通です。
  $http_response_header に入るステータス行は、先頭の126バイトまでとなります。

7. 要求行のHTTPのバージョン(PHP 5.6、7.0)

  PHP 5.6と7.0では、2025年に提供したセキュリティ修正以降、"protocol_version" オプションを
  指定しない場合の要求行が HTTP/1.1 になっています(上流のPHP 5.6、7.0では HTTP/1.0)。
  本リリースではこの動作を変更していません。同梱テストのうち、HTTP/1.0 の要求行を前提と
  していたものは、HTTP/1.1 を前提とするよう変更しています。

8. 同梱テストの変更

  緩い解釈を前提とする同梱テストは、http_header_parse_strict=0 を明示するよう変更して
  います。PHP 8.1では bug61548.phpt、ghsa-hgf5-96fm-v528-001.phpt、
  network/http-stream.phpt の3本、PHP 5.4~8.0では bug61548.phpt と
  network/http-stream.phpt の2本、PHP 5.3では network/http-stream.phpt の1本です。

  また、ext/standard/tests/http/ に次のテストを追加しています。

    http_header_parse_strict-request.phpt、-response.phpt、-injection.phpt
      両方向の検査と、拒否される値を On/Off の両モードで確認します。
    http_header_parse_strict-status-line.phpt
      CRLFが読み込み領域の境目で分かれるステータス行を確認します。
    http_header_parse_strict-1xx.phpt
      1xx応答の後の各行の扱いを確認します(PHP 5.3にはありません)。
    http_header_parse_strict-proxy-long-line.phpt
      プロキシのCONNECT応答の長いヘッダー行を確認します。
    http_header_parse_strict-no-context.phpt
      ストリームコンテキスト無しでURLを読み込む場合のINI設定の検査を確認します。
    http_header_parse_strict-notification.phpt
      通知コールバックが接続後に "method"、"user_agent"、user_agent/from を書き換えた
      場合の検査を確認します。
    ghsa-hgf5-96fm-v528-004.phpt
      値に "authorization:" を含むだけのヘッダーによって、本来のBasic認証の
      Authorizationヘッダーが抑止されないことを両モードで確認します。
    gh9316.phpt(PHP 5.3~5.5、7.1~7.4)
      長いステータス行の扱いを確認します。
    http_wrapper_in_function.phpt(PHP 5.6)
      関数内から http:// のURLを開く場合を確認します(下記の別項目を参照してください)。

■ 備考
本サービスでは通常、セキュリティ修正でINI設定を追加することはありません。本件は、RFC
準拠の厳格な解釈が脆弱性を塞ぐ一方、アプリケーションを変更できないお客様には従来の挙動へ
戻す手段が必要である為、例外として追加しています。

http_header_parse_strict は PHP_INI_ALL である為、スクリプトから ini_set() で変更でき
ます。同一プロセス内のコードに対する防御境界ではない点にご留意ください。

この設定値を保持する変数は、ファイル関連のグローバル構造体(php_file_globals)の末尾に
追加しています。既存のメンバーの位置は変わらない為、修正前のヘッダーファイルでビルドした
拡張モジュールにも影響しません。

PHP 5.3以降のサポート対象バージョンすべてに適用しています。


=================================================================================
- Streams:
 . 関数内から http:// のURLを開くとプロセスが異常終了する問題を修正(PHP 5.6)。

■ 脆弱性修正ではありません。

2025年に提供したセキュリティ修正で生じた不具合の修正です。

■ 影響バージョン
PHP 5.6

■ 互換性問題
なし。

■ 解説
PHP 5.6で、関数の中から fopen()、file_get_contents() 等で http:// のURLを開くと、
プロセスが異常終了(セグメンテーション違反)していました。

http:// ストリームラッパーは、呼び出し元の変数 $http_response_header を設定します。関数の
変数表は必要になるまで作られない為、上流のPHP 5.6では設定の前に変数表を作る処理を呼んで
います。2025年に提供したセキュリティ修正でこの処理が失われていた為、変数表がまだ無い関数
の中から呼び出すと異常終了していました。上流のPHP 5.6.40と同じ処理を戻しています。


=================================================================================
- Date:
 . Fixed leak on double DatePeriod::__construct() call. (ilutov)

■ 脆弱性修正ではありません。

上流のPHP 8.2.33に含まれる修正の為、取り込んでいます(CVE/GHSAの割り当てはありません)。

■ 影響バージョン
PHP 5.3以降

■ 互換性問題
あり。

初期化されていないDateIntervalオブジェクトをDatePeriodのコンストラクタに渡した場合、例外が
発生するようになりました。初期化されていないDateIntervalとは、
ReflectionClass::newInstanceWithoutConstructor()(PHP 5.6以降)で生成したものや、コンストラクタ
でparent::__construct()を呼び出さないDateIntervalの派生クラスのオブジェクトなどです。

- PHP 8.0/8.1: Error例外
 "The DateInterval object has not been correctly initialized by its constructor"
- PHP 5.3~7.4: Exception例外
 "DatePeriod::__construct(): The DateInterval object has not been correctly initialized by its constructor"

修正前は初期化されていない内部データ(NULLポインタ)をそのまま複製しようとする為、
プロセスが異常終了していました。通常の方法で生成したDateIntervalを使用している
アプリケーションには影響ありません。

PHP 7.4以前でError例外ではなくException例外となるのは、これらのバージョンの
DatePeriod::__construct()が、不正なISO 8601文字列など他の全てのエラーもException例外として
報告している為です。上流の8.xと同じError例外にはせず、各バージョンの既存のエラー報告方法に
合わせています。

また、生成済みのDatePeriodオブジェクトに対して__construct()を再度呼び出した場合の動作が変わり
ます。修正前は、再度の呼び出しで指定しなかった値(終了日時など)が以前の値のまま残っていました。
修正後は、再度の呼び出しで与えた値だけでオブジェクトを設定し直します。

例えば、終了日時を指定して生成したオブジェクトに対して、終了日時を指定せず繰り返し回数0で
__construct()を再度呼び出した場合、修正前は以前の終了日時が残って成功していました。修正後は、
PHP 7.2~8.1では繰り返し回数が不正である旨の例外となり、PHP 7.1以前では以前の終了日時が使われ
なくなります。

再度の呼び出しが例外で失敗した場合(例外をcatchした場合)のオブジェクトの状態は、次の通りです。
引数がどの呼び出し形式にも合わない場合は、全てのバージョンでオブジェクトは変わりません。

- PHP 8.0/8.1: 上流のPHP 8.2.33と同じく呼び出しの最初にオブジェクトを初期化する為、失敗する
 までに設定された値だけが残ります。値が設定されていない場合、getStartDate()と
 getDateInterval()はError例外 "The DatePeriod object has not been correctly initialized by its
 constructor"、foreachによる反復はError例外 "DatePeriod has not been initialized correctly"
 となり、getEndDate()とgetRecurrences()はNULLを返します。ISO 8601文字列を渡した場合、
 getStartDate()とgetEndDate()が返すオブジェクトのクラスはDateTimeになります。
 上流の修正をそのまま適用すると、一部だけ解析できるISO 8601文字列(例えば
 "R5/2008-03-01T13:00:00Z" のように間隔が欠けているもの)で失敗した後にgetStartDate()を
 (文字列に終了日時が含まれる場合はgetEndDate()も)呼び出すとプロセスが異常終了しますが、
 本サービスではこれを修正しています。
- PHP 5.3~7.4: ISO 8601文字列の解析や、DateIntervalが初期化されているかの検査が済んでから
 初期化する為、解析できないISO 8601文字列や初期化されていないDateIntervalで失敗した場合、
 開始日時・終了日時・間隔は以前の値のまま残ります(解析できない文字列の場合は修正前と同じ動作
 です)。それ以外の理由で例外となった場合(PHP 7.2~7.4で繰り返し回数が不正な場合など)は、例外と
 なってもオブジェクトは新しい値で設定されます。

なお、間隔などが欠けたISO 8601文字列を渡して失敗したオブジェクトに対して、foreachで反復したり、
PHP 5.6~7.4でgetStartDate()やgetDateInterval()を呼び出したりするとプロセスが異常終了する問題は
修正前からあり、この修正では変わりません。

■ 解説
生成済みのDatePeriodオブジェクトに対して__construct()を再度呼び出すと、それまで保持していた
開始日時・終了日時・現在日時・間隔のデータが解放されないまま上書きされ、メモリリークが発生
していました。再度呼び出された場合は、それらを解放してから初期化し直すように修正しています。


=================================================================================
- GD:
 . Upgrade libgd. (CVE-2026-9672) (Pierre Joye)

■ GIF画像の読み込み処理で未初期化メモリの参照が発生する

■ 影響バージョン
PHP 5.3以降(PHPに同梱のlibgdを使用するビルド)

本サービスで提供するRPMは、全てのバージョンでPHPに同梱のlibgdを使用しており、本修正が適用
されます。

次のパッケージは、これまでOSが提供するlibgdを使用しており、同梱のlibgdの修正が適用されて
いませんでした。本修正を適用する為、今回のリリースから同梱のlibgdを使用するように変更しています。

- PHP 8.1(全てのOS向け)
- PHP 5.4(Amazon Linux 2023向け)
- PHP 5.5(Amazon Linux 2023向け)

■ 互換性問題
上記の3つのパッケージのみ、あり。

- PHP 8.1: 使用できる関数と対応する画像形式は変わりません。GD拡張のバージョン情報が変わります。
 - gd_info()の "GD Version" が、OSのlibgdのバージョン(例えば "2.2.5")から
   "bundled (2.1.0 compatible)" になります。
 - 定数 GD_BUNDLED が 0 から 1 に、GD_VERSION、GD_MAJOR_VERSION、GD_MINOR_VERSION、
   GD_RELEASE_VERSION が同梱のlibgdの値(2.0.35)になります。
 - AlmaLinux 8向けのみ、定数 IMG_WEBP_LOSSLESS が新たに定義されます(AlmaLinux 9/10では
   以前から定義されています)。
- PHP 5.5(Amazon Linux 2023向け): 対応する画像形式は変わりません。上記と同じくバージョン情報が
 変わり、関数 imageantialias() が使用できるようになります(PHP 5.xでは同梱のlibgdを使用する
 場合にだけ提供される関数の為)。
- PHP 5.4(Amazon Linux 2023向け): これまでのパッケージでは、GD拡張がOSのlibgdに無い関数
 (gdGetC)を必要とする為に読み込めず、GD拡張の関数を使用できませんでした。今回のリリースから
 GD拡張を使用できるようになります。

これらのバージョン情報や関数・定数の有無で処理を分けているアプリケーションは影響を受ける
可能性があります。

上記以外のパッケージは特になし。

■ 解説
PHPに同梱のlibgdのGIFデコーダ(LZW伸長処理)に、次の3つの問題がありました。

- 伸長テーブルの初期化処理が誤った位置に書き込み、テーブルの大部分が未初期化のまま残る。
- 終了コードを受け取っても処理を終了せず、通常のデータとして処理を続けてしまう。
- 伸長処理の状態を保持する領域をスタック上で初期化せずに使用している。

細工したGIF画像をimagecreatefromgif()などで読み込ませると、未初期化のメモリの内容に基づいて
伸長処理が行われ、メモリ内容の漏洩やクラッシュ(DoS)につながる可能性があります。
利用者がアップロードした画像を処理するアプリケーションなどが影響を受けます。

上流の修正にはテストが含まれていない為、細工したGIF画像を用いてvalgrindで確認しています。
同梱のlibgdを使用するPHP 8.1の開発ビルドで、修正前は未初期化の値の使用が4件検出され、修正後は
検出されないことを確認しています。


=================================================================================
- PGSQL:
 . Fixed GHSA-7qpv-r5mr-78m4 (SQL injection via E'...' backslash breakout).
   (CVE-2026-17543) (ilutov)

■ pg_insert()、pg_update()、pg_delete()、pg_select()などでSQLインジェクションが可能

■ 影響バージョン
PHP 5.4以降

PHP 5.3は文字列リテラルにE'...'形式を使用していない為、該当しません。

■ 互換性問題
あり。

文字列リテラルの形式がE'...'から'...'に変わります。上流と同じ変更です。

- pg_convert()が返す配列の値が変わります(例: "E'AAA'" が "'AAA'" になります)。
- pg_insert()、pg_update()、pg_delete()、pg_select()にPGSQL_DML_STRINGオプションを指定して
 取得するSQL文字列が変わります。

 修正前: INSERT INTO "t" ("num","str") VALUES (1234,E'AAA');
 修正後: INSERT INTO "t" ("num","str") VALUES (1234,'AAA');

これらの戻り値を文字列として比較したり、ログと照合したりしているアプリケーションは影響を
受けます。

データベースでの扱いは、接続のstandard_conforming_stringsの設定によって次のようになります。
書き込み(pg_insert()、pg_update())だけでなく、検索条件(pg_select()、pg_delete()、
pg_update()のWHERE句)に指定した値も同じです。

- off の場合: 格納される値や検索結果は修正前と同じです。ただし、バックスラッシュを含む
 文字列の値と、全てのbytea型の値(エスケープ結果が必ずバックスラッシュを含む為)について、
 PostgreSQLが「WARNING: nonstandard use of \\ in a string literal」という警告を出すように
 なります(escape_string_warningの既定値がonの為)。
- on の場合(PostgreSQL 9.1以降の既定値):
 - 文字列型の列: バックスラッシュを含まない値は修正前と同じです。バックスラッシュを含む値は、
   修正前はバックスラッシュがエスケープ文字として解釈され、渡した値と異なる値が格納されたり、
   検索条件が一致しなかったりしていました。末尾が奇数個のバックスラッシュで終わる値(例えば
   "C:\dir\")や、"\u" の後に正しい4桁の16進数が続かない値などでは、SQL文がエラーになり
   書き込めませんでした。
   修正後は渡した値がそのまま使われ、エラーになっていた書き込みは成功するようになります。
 - bytea型の列(PostgreSQL 9.0以降のhex形式): 修正前は値の先頭の1バイトが誤って解釈されて
   いました。
   - 先頭が0x00の値: エラーとなり、書き込めませんでした。
   - 先頭が0x5c(バックスラッシュ)の値: 多くの場合エラー(invalid input syntax for type
     bytea)となり、書き込めませんでした。一部の値は誤った値で格納されていました。
   - 先頭が0x80以上の値(JPEGやPNGなど多くのバイナリデータ): データベースの文字コードが
     UTF-8などの場合はエラー(invalid byte sequence)となり、書き込めませんでした。SQL_ASCIIの
     場合は誤った値で格納されていました。
   - それ以外の2バイト以上の値: 誤った値で格納されていました(例えば "BBB" が "B4242" として
     格納される)。
   - 1バイトだけの値(上記以外): 正しく格納されていました。
   修正後は正しい値が格納されます。エラーになっていた書き込みは成功するようになります。
   誤った値で格納された値は誤ったまま残りますので、必要に応じて確認してください。
 - 検索条件にbytea型の値やバックスラッシュを含む値を指定していた場合、修正前は一致しなかった
   (またはエラーになった)行が、修正後は一致するようになります。pg_select()で返る行や、
   pg_delete()、pg_update()で削除・更新される行が変わることがあります。

■ 解説
これらの関数は、文字列の値をPQescapeStringConn()でエスケープした上でE'...'で囲んでいました。
PQescapeStringConn()は接続のstandard_conforming_stringsの設定に従い、onの場合は
バックスラッシュをエスケープしません。一方E'...'の中ではバックスラッシュが常にエスケープ
文字として扱われる為、値に「\'」が含まれると、エスケープしたはずの引用符が文字列リテラルの
終端として解釈され、以降の文字列がSQLとして実行されます。

例えば pg_select($db, 'users', ['name' => "x\\' OR 1=1 --"]) のように、外部からの値を
そのまま渡すと、WHERE句の条件が無効化されて全ての行が返されます。pg_insert()では、
他の列の値を書き換えることもできます。

PQescapeStringConn()は'...'形式の文字列リテラルと組み合わせて使用するものなので、'...'で
囲むように修正しています。修正前のコードでは細工した値で全ての行が返され、修正後は返されない
ことを確認しています。


=================================================================================
- Phar:
 . Fixed GHSA-vc5h-9ppw-p5f3 (Crash via recursive symlinks). (CVE-2026-7260)
   (Jakub Zelenka)

■ 循環したシンボリックリンクを含むtar形式のアーカイブでスタックオーバーフローが発生する

■ 影響バージョン
PHP 5.3以降

■ 互換性問題
特になし。

シンボリックリンクを持てるのはtar形式のアーカイブ(tar形式のpharを含む)だけです。循環した
シンボリックリンクのエントリは、修正前はクラッシュしていましたが、修正後は次のようになります。

- PharFileInfo::getContent()で読み込んだ場合: 空の内容が返ります。
- phar://ストリーム(fopen()、file_get_contents()、includeなど)で開いた場合: 警告
 ("... is not a file in phar ...")が出て、開くのに失敗します。

また、本サービス独自の追加修正(解説を参照)により、サブディレクトリにあるシンボリックリンクの
エントリを2回以上辿ると2回目以降にリンク先が見つからなかった、以前からの問題も修正されます。

■ 解説
Pharはtar形式のアーカイブ内のシンボリックリンクを再帰呼び出しで辿っていた為、エントリ同士が
循環して参照し合うアーカイブを読み込むと、スタックを使い切ってプロセスが異常終了(DoS)
していました。シンボリックリンクを繰り返し処理で辿り、循環を検出したら処理を打ち切るように
修正しています。

上流の修正だけでは、アーカイブ内のサブディレクトリにシンボリックリンクが連なっている場合に、
循環していなくてもプロセスが異常終了します(例えば d/a→b→c→e→f→g のように5段以上連なる
場合)。リンク先のパスを組み立てる処理がエントリ名を途中で切り詰めたまま
元に戻さない為、同じエントリを2回目に辿ったときにリンク先を見つけられなくなり、その結果を
検査せずに参照していました。本サービスではこの問題も合わせて修正しています(上流の
開発版にも同じ問題が残っています)。

利用者がアップロードしたtar形式のアーカイブを開くアプリケーションなどが影響を受けます。