Article

PgBouncer 1.26.0の脆弱性修正:認証前の停止リスクと更新手順

PgBouncer 1.26.0は3件のCVEを修正し、うち2件は認証前にサービスを停止させる問題です。SCRAM認証の適用条件、暫定緩和策の限界、旧オンライン再起動の削除を踏まえ、プーラーを独立した更新対象として扱う理由を整理します。

Share

こはるの読みどころ

DB本体の更新だけでは、途中のプーラーまで直ったとは限らないね。認証設定の名前と実際の動作、更新時の再接続までつなげて読んでみよう!

こはるの読みどころ

PostgreSQLを更新していても、その手前で接続を受けるPgBouncerまで更新できているでしょうか。接続経路に別のプロセスが入る構成では、データベース本体の保守だけで経路全体を守れるとは限りません。

Christophe Pettus氏の「Nobody Patches the Pooler」は、この見落としに注意を促しています。きっかけは、2026年9月23日に公開されたPgBouncer 1.26.0のセキュリティ修正です。公式のリリース告知でも、3件のCVEと、そのうち2件が認証前に引き起こせることを確認できます。

対応の焦点は、パスワードを強くすることよりも、どの処理が認証前に動き、どのプロセスを更新する必要があるかです。障害が広がる仕組みから、更新までの緩和策、既存の再起動手順で見直す箇所へ順にたどります。

認証前の処理がPgBouncer全体を止める理由

PgBouncerは、アプリケーションとPostgreSQLの間で接続を受け持ちます。今回の問題では、その共有プロセスのクラッシュや処理の停止によって、同じプロセスが扱うほかの接続も巻き込まれます。対象はPgBouncerの修正であり、PostgreSQL本体のバージョンだけでは修正済みか判断できません。

3件は、入力が届く方向と止まり方が異なります。

脆弱性 引き金となる入力・条件 結果
CVE-2026-19888 クライアント側のSCRAM認証メッセージに必須属性がない。資格情報の検証前に到達する NULLポインター参照によるクラッシュで、そのプロセスの接続が切れる
CVE-2026-6668 大きな入力によるバッファ拡張時の整数オーバーフロー。既定のパケット上限では認証前にも到達する 無限ループでCPUコアを占有し、そのプロセスの接続処理が止まる
CVE-2026-6669 悪意のある、または侵害されたバックエンドがSCRAM認証で過大な反復回数を指定する 認証計算がCPUを消費し、ほかのデータベースやクライアントも待たされる

いずれも1.26.0より前の修正対象です。特にクラッシュの問題は、SCRAM対応が入った1.11.0から存在します。1.26.0ではサーバーから受け付けるSCRAM反復回数にも100万回の上限が設けられました。変更履歴

ここで見落としやすいのが、認証方式の設定名です。auth_type = md5 でも、ユーザーの保存済み認証情報がSCRAM形式なら、実際にはSCRAM認証へ切り替わります。設定に scram-sha-256 と書いていないだけでは、対象外とは判断できないわけですね。認証設定の説明

更新までの緩和策は、入口制限とパケット上限で役割が違う

まずは、稼働中のPgBouncerとその設定を特定します。管理用データベース pgbouncer に、管理コンソールへのアクセスを許可されたユーザーで接続し、次の読み取り用コマンドを実行できます。管理コンソールの仕様

SQL
-- 稼働中のPgBouncerのバージョンを表示します。
SHOW VERSION;
-- 現在の設定値を表示します。
SHOW CONFIG;

確認したいのは、修正版1.26.0の適用状況、auth_type、max_packet_size、そして待受ポートへ接続できる範囲です。配布パッケージやマネージドサービスでは、提供元の修正適用情報も併せて判断します。

更新まで時間が必要なら、クラッシュへの緩和策は、待受ポートへのネットワークアクセスを信頼できるクライアントに限定することです。存在しないユーザー名でも模擬SCRAM交換が行われるため、有効なアカウントを渡さないだけでは防げません。CVE-2026-19888の条件と緩和策

無限ループには、max_packet_size を 1073741824 より十分小さくする緩和策があります。ただし、これは3件すべてを解消する設定ではありません。CVE-2026-6668の緩和策

この上限は結果セット全体のサイズではなく、クエリーや結果の1行など、個々のPostgreSQLパケットに対するものです。小さくする値は、正当な大きいクエリーや行を通せるかも踏まえて選びたいところです。パケットサイズ設定の仕様

1.26.0への更新では、旧再起動方式と接続状態を見直す

修正を適用する際には、バイナリーの入れ替えだけでなく起動手順も見直します。1.26.0では、非推奨だったオンライン再起動の -R と、それを支える SHOW FDS、SUSPEND が削除されました。これらを呼ぶデプロイスクリプトは、そのまま使えません。1.26.0の変更履歴

代替となるローリング再起動は、複数プロセスで接続を受け、1つずつ切り替える構成が前提です。so_reuseport を使う場合はOSの対応を確かめ、プロセスごとのUnixソケットやPIDファイルを分けます。クエリーキャンセルの転送にはpeeringの設定も関係します。複数プロセスの設定条件

SHUTDOWN WAIT_FOR_CLIENTS は、新規接続の受け付けを止め、既存クライアントが切断するまで終了を待ちます。そのため、長く接続を保持するアプリケーションでは、再接続させる方法も更新手順に含める必要があります。公式のローリング再起動手順

接続を再利用する際の設定管理にも変更があります。1.26.0はPostgreSQLが報告するパラメーターを既定で追跡し、search_path はPostgreSQL 18以降、default_transaction_read_only は14以降が対象です。トランザクションプーリングでは、別クライアントへ設定が残る挙動に依存していないか、検証環境で接続を使い回して確かめるとよいでしょう。パラメーター追跡の変更

疎通監視もPgBouncerを通すと、利用者の接続経路を確かめられる

無限ループで処理が止まる場合、プロセスが存在することと、SQLへ応答できることは別です。PostgreSQLへの直接接続だけが成功しても、アプリケーションからの経路が使える証拠にはなりません。

そこで運用上の確認として、PgBouncerを経由し、アプリケーション用データベースへ短いクエリーを発行して、応答時間と失敗を観測する方法が考えられます。たとえば SELECT 1; のような疎通確認です。これは脆弱性を再現する試験ではなく、利用者と同じ経路で応答が返るかを見るための提案です。

今回必要なのは、PgBouncerを独立した更新対象として扱い、修正版へ切り替わったことを稼働プロセスと接続経路の両方で確かめることです。ネットワーク制限やパケット上限は更新までの補助と位置付け、プーラーの更新担当と再起動手順をデータベースの保守計画に組み込むところまで進めたいですね。

出典

Share

Related Articles

カテゴリやタグが近い記事を続けて読めるように並べています。