PostgreSQLに新たな脆弱性

 PostgreSQLウォッチ 第35回では,PostgreSQLのセキュリティリリースと,SECURITY DEFINER関数(他のユーザー権限で実行できる関数)の利用に伴うコアメンバーからの「セキュリティ勧告」をお伝えした。今回新たに見つかった脆弱性は,またもSECURITY DEFINERにかかわるものである。

スキーマサーチパスの問題

 今回見つかったSECURITY DEFINER関数の脆弱性の問題に触れる前に,前回の「セキュリティ勧告」について復習しておこう。今回の脆弱性も問題の根は共通しているからである。

 PostgreSQLには,「スキーマ」という概念がある。スキーマは名前空間である。スキーマが異なれば同じ名前のテーブルを作成できる。これはUNIXにおいて,ディレクトリが異なれば同じ名前のファイルを置けるのと同じようなものだ。スキーマを使い分けるには2つの方法がある。一つはスキーマ名を明示的にオブジェクト名に付与する方法だ。例えば,

public.t1

 ならばスキーマ「public」の「t1」というオブジェクトを指定したことになる。

 もう一つは「スキーマサーチパス」を使う方法だ。スキーマ名を省略したときに,どのスキーマを優先的に割り当てるかを指定するものだ。現在のスキーマサーチパスは,「show search_path」で確認できる。

test=> show search_path;
  search_path   
----------------
 "$user",public
(1 row)

 この例では,$user,すなわち現在ログイン中のDBユーザー名が最優先,続いて「public」というスキーマが検索されることが分かる。ちなみにpublicは,いわば「デフォルト」のスキーマで,何もスキーマを指定しなければpublic スキーマにオブジェクトが作成される。

pg_catalogスキーマを利用した攻撃

 この他にシステムカタログや組み込み関数,オペレータなどが登録されている「pg_catalog」というスキーマがある。pg_catalogはスキーマサーチパスにが含まれていない場合でも常に検索対象になり,しかも常に最初に検索される。PostgreSQLは組み込みの型やオペレータなどはすべてpg_catalogスキーマに登録されているので,こういう配慮がされているわけである。

 ところが明示的にpg_catalogをスキーマサーチパスに追加すると,その順序で検索が行われる。つまり,組み込みの型やオペレータなどと同じ名前のオブジェクトを用意しておけば,pg_catalogに登録されている「正規の」オブジェクトの代わりに使用されてしまうことが起こり得る。こうしてSECURITY DEFINERな関数の中で使われているオブジェクトを,悪意のあるユーザーが用意したオブジェクトに置き換え,他人の権限で実行する攻撃が成立するわけだ。

 それに対する対策は,SECURITY DEFINER関数の中で,安全なスキーマだけをスキーマサーチパスに設定することである。

 前回説明した「セキュリティ勧告」はこのようなものであった。