Home Explore Blog CI



postgresql

28th chunk of `doc/src/sgml/rules.sgml`
b56ac484af419b020b860c57b521f5e75f2bb47937069e8b0000000100000fa3
 <literal>INSERT</literal>, <literal>UPDATE</literal>, and <literal>DELETE</literal> on
    the <literal>shoelace</literal> view to someone else, but only
    <literal>SELECT</literal> on <literal>shoelace_log</literal>. The rule action to
    write log entries will still be executed successfully, and that
    other user could see the log entries.  But they could not create fake
    entries, nor could they manipulate or remove existing ones.  In this
    case, there is no possibility of subverting the rules by convincing
    the planner to alter the order of operations, because the only rule
    which references <literal>shoelace_log</literal> is an unqualified
    <literal>INSERT</literal>.  This might not be true in more complex scenarios.
</para>

<para>
    When it is necessary for a view to provide row-level security, the
    <literal>security_barrier</literal> attribute should be applied to
    the view.  This prevents maliciously-chosen functions and operators from
    being passed values from rows until after the view has done its work.  For
    example, if the view shown above had been created like this, it would
    be secure:
<programlisting>
CREATE VIEW phone_number WITH (security_barrier) AS
    SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
</programlisting>
    Views created with the <literal>security_barrier</literal> may perform
    far worse than views created without this option.  In general, there is
    no way to avoid this: the fastest possible plan must be rejected
    if it may compromise security.  For this reason, this option is not
    enabled by default.
</para>

<para>
    The query planner has more flexibility when dealing with functions that
    have no side effects.  Such functions are referred to as <literal>LEAKPROOF</literal>, and
    include many simple, commonly used operators, such as many equality
    operators.  The query planner can safely allow such functions to be evaluated
    at any point in the query execution process, since invoking them on rows
    invisible to the user will not leak any information about the unseen rows.
    Further, functions which do not take arguments or which are not passed any
    arguments from the security barrier view do not have to be marked as
    <literal>LEAKPROOF</literal> to be pushed down, as they never receive data
    from the view.  In contrast, a function that might throw an error depending
    on the values received as arguments (such as one that throws an error in the
    event of overflow or division by zero) is not leakproof, and could provide
    significant information about the unseen rows if applied before the security
    view's row filters.
</para>

<para>
    For example, an index scan cannot be selected for queries on security
    barrier views (or tables with row-level security policies) if an
    operator used in the <literal>WHERE</literal> clause is associated with the
    operator family of the index, but its underlying function is not marked
    <literal>LEAKPROOF</literal>. The <xref linkend="app-psql"/> program's
    <command><link linkend="app-psql-meta-command-dao">\dAo+</link></command>
    meta-command is useful to list operator families and determine which of
    their operators are marked as leakproof.
</para>

<para>
    It is important to understand that even a view created with the
    <literal>security_barrier</literal> option is intended to be secure only
    in the limited sense that the contents of the invisible tuples will not be
    passed to possibly-insecure functions.  The user may well have other means
    of making inferences about the unseen data; for example, they can see the
    query plan using <command>EXPLAIN</command>, or measure the run time of
    queries against the view.  A malicious attacker might be able to infer
    something about the amount of unseen data, or even gain some information
    about the data distribution or most common values (since these things may
    affect

Title: Row-Level Security and View Security Barriers
Summary
This section discusses how to implement row-level security in PostgreSQL using the security_barrier attribute on views, which prevents malicious functions from accessing sensitive data, and explains the trade-offs in performance and security, as well as the importance of marking functions as LEAKPROOF to ensure secure query execution.