{use}と{select}

SE-PostgreSQLで行を参照する際にチェックされるパーミッションには{use}と{select}の2種類がある。
例えば、以下のSQL構文の場合

SELECT name,price FROM drink WHERE id in (2,3,4);
nameおよびprice行には{select}パーミッションのチェックが適用されるが、id行には{use}パーミッションが適用される。
この違いは、行の中身を利用者に返すか否かである。

『行の参照』という点では同様だが、{select}が評価されるのは、行の内容を参照しそれを利用者に返却する時。一方、{use}が評価されるのは、行の内容を参照するが利用者に返却しない時。例えば、WHERE句での利用や、GROUP BY句での利用にあたる。

但し、WHERE句での利用であれば、盲目的に{use}を評価するワケではない。以下の例を考えてみよう。

CREATE OR REPLACE FUNCTION malicious_func(TEXT)
LANGUAGE 'sql' RETURNS bool AS
'INSERT INTO leak_info VALUES($1);
SELECT true';
DELETE FROM drink WHERE malicious_func(name || ',' || price);
この例ではmalicious_func()という関数を定義している。この関数は、引数をleak_infoというテーブルに叩き込んで、単純にtrueを返却する。

もし、WHERE句に対して盲目的に{use}パーミッションを適用したらどうなるだろう?上の例では、DELETE構文のWHERE句でmalicious_func()関数を呼んでいるが、この時、{delete}と{use}しか評価されなければ、{select}パーミッションが無くてもデータを正当な手段で読み出せてしまうことになる。

したがって、{use}パーミッションを適用する際には、より厳格な制約を適用する必要がある。すなわち『リファレンスモニタは、その参照が利用者に返却されない事が確実である場合に、{select}に換えて{use}パーミッションを評価する事ができる』という形になる。

SE-PostgreSQLは、ビルトイン関数は信用できるが、ユーザ定義関数は信用ならないと考え、ビルトイン関数の引数リストには{use}パーミッションを、それ以外の関数の引数リストには{select}パーミッションを適用する。