本文へ移動

psqlODBC で IN 句を入力から組むアプリにヒープ破損、18.00.0005 で修正

ユーザー入力の数だけ IN (?, ...) を並べるアプリが当たる psqlODBC の CVE-2026-109448。影響バージョン、18.00.0005 で返る SQLSTATE 07009、すぐ上げられないときの回避策を整理する。

32767 18.00.0005 で SQLBindParameter が受け付けるパラメータ番号の上限 これを超える番号は SQLSTATE 07009 で拒否される(psqlODBC 18.00.0005 のお知らせ、2026年10月14日)

ユーザーが選んだ値の数だけ IN (?, ?, ...) のプレースホルダを並べ、psqlODBC 経由で PostgreSQL に投げているアプリは、CVE-2026-109448 の条件に当たる。影響を受けるのは psqlODBC の 08.01.0102 から 18.00.0004 まで。修正版の 18.00.0005 は2026年10月14日に PostgreSQL のニュースで公開され、全ユーザーにアップグレードを求めている。

修正版では、上限を超えるパラメータ番号を SQLBindParameter が SQLSTATE 07009 で拒否する。これまで正常に動いていたアプリがこの変更で動かなくなることはない、とお知らせは説明している。その理由は ODBC の仕様側にあり、後の節で触れる。

数万個のパラメータを束縛したときに起きること

psqlODBC は、ステートメントに束縛されたパラメータの数を符号付き 16 ビットのフィールドに持っていた。上限を超えて束縛すると、ドライバはパラメータの束縛情報を持つメモリの外側にゼロを書き込む。結果としてアプリはクラッシュするか、壊れたメモリを抱えたまま動き続ける。CVSS 3.1 の基本値は 5.9(Medium)とされている。

お知らせが露出の条件として挙げるのは、信頼できない入力が束縛するパラメータの数を決められることだ。例として、ユーザーが渡した値から IN (?, ?, ...) のリストを組み立てる実装が名指しされている。検索画面で複数選択した ID をそのまま IN 句に展開する、CSV で受け取った値を一括で照会する、といった作りが思い当たるなら確認の対象になる。

しきい値の書き方は、お知らせの中で揃っていない。見出しは「32767 を超えるパラメータ」、本文の説明は「32768 を超えるパラメータを束縛したとき」にメモリ破損が起きるとしている。1個の差がどちらなのかはこのお知らせからは確定できない。修正版が拒否を始める境界は 32767 と明記されている。

07009 が返るようになっても既存アプリが壊れない理由

ODBC は 32767 を超えるパラメータ数をそもそも報告できない。SQLNumParams と SQL_DESC_COUNT が 16 ビットの値だからだ。お知らせによれば、これまでのどのリリースでも 32767 を超えるパラメータを持つステートメントは実行できなかった。修正で新たに弾かれるのは、もともと成功しなかった呼び出しだけということになる。

アプリから見た違いは、メモリ破損やクラッシュが起きていた場面で、束縛の時点でエラーが返るようになる点だ。SQLBindParameter の戻り値を確認せずに先へ進む実装だと、このエラーを取りこぼす。更新と合わせて、束縛失敗をどう扱っているかを見ておくとよい。

すぐに上げられないときの回避策

お知らせが示す回避策は 2つある。

  1. 外部入力から組み立てるパラメータの数に上限を設ける
  2. 長い値のリストは配列のパラメータ 1つにまとめて渡す(例として = ANY(?) が挙げられている)

2つ目は、IN (?, ?, ...) を = ANY(?) に置き換え、値の一覧を 1個の配列として束縛する形だ。パラメータ数が入力の件数に左右されなくなるので、この脆弱性の条件から外れる。配列の値を ODBC からどの型・どの表記で束縛するかまではお知らせに書かれていないため、自分のアプリで動作を確かめてから切り替えたい。

同じリリースに入った 2つのバグ修正

18.00.0005 にはセキュリティ修正のほかにバグ修正が 2件入っている。IN 句を大きく組むアプリには 1件目も関係する。

  • サーバー側で prepare したステートメントのパラメータが1000個以上あると、type "timestam" does not exist のようなエラーで失敗することがあった。パラメータ 1000 番目以降で、各パラメータに続く型名を固定長のバッファに収めるために切り詰めていたのが原因だ。
  • 18.00.0003 以降、Microsoft の OLE DB Provider for ODBC(MSDASQL)経由、たとえば ADO から使うと、bytea パラメータが Type is invalid で失敗していた。

Windows 向けのパッケージは OpenSSL 3.5.9 でビルドされるようになった。x86、x64、ARM64 のインストーラーとマージモジュールが PostgreSQL のダウンロードサイトと GitHub のリリースページにある。

BI ツールや業務アプリにドライバを同梱している場合、手元で確認するのは同梱している psqlODBC のバージョンと、入力の件数でプレースホルダの数が変わるクエリがあるかの 2点になる。前者が 18.00.0004 以下で後者がある構成は、更新を優先する。どちらかを満たさないなら、急ぎの度合いは下がるものの、お知らせは全ユーザーに更新を勧めている。

出典 種別について