mirror of
https://github.com/postgres/postgres.git
synced 2025-06-11 20:28:21 +03:00
Add a security_barrier option for views.
When a view is marked as a security barrier, it will not be pulled up into the containing query, and no quals will be pushed down into it, so that no function or operator chosen by the user can be applied to rows not exposed by the view. Views not configured with this option cannot provide robust row-level security, but will perform far better. Patch by KaiGai Kohei; original problem report by Heikki Linnakangas (in October 2009!). Review (in earlier versions) by Noah Misch and others. Design advice by Tom Lane and myself. Further review and cleanup by me.
This commit is contained in:
@ -26,6 +26,8 @@ ALTER VIEW <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <r
|
||||
ALTER VIEW <replaceable class="parameter">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
|
||||
ALTER VIEW <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
|
||||
ALTER VIEW <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
|
||||
ALTER VIEW <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] )
|
||||
ALTER VIEW <replaceable class="parameter">name</replaceable> RESET ( <replaceable class="parameter">view_option_name</replaceable> [, ... ] )
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -102,6 +104,24 @@ ALTER VIEW <replaceable class="parameter">name</replaceable> SET SCHEMA <replace
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">view_option_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of a view option to be set or reset.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">view_option_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The new value for a view option.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -22,6 +22,7 @@ PostgreSQL documentation
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW <replaceable class="PARAMETER">name</replaceable> [ ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ]
|
||||
[ WITH ( <replaceable class="PARAMETER">view_option_name</replaceable> [= <replaceable class="PARAMETER">view_option_value</replaceable>] [, ... ] ) ]
|
||||
AS <replaceable class="PARAMETER">query</replaceable>
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
@ -98,6 +99,18 @@ CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW <replaceable class="PARAMETER">n
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>WITH ( <replaceable class="PARAMETER">view_option_name</replaceable> [= <replaceable class="PARAMETER">view_option_value</replaceable>] [, ... ] )</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This clause specifies optional parameters for a view; currently, the
|
||||
only suppored parameter name is <literal>security_barrier</literal>,
|
||||
which should be enabled when a view is intended to provide row-level
|
||||
security. See <xref linkend="rules-privileges"> for full details.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">query</replaceable></term>
|
||||
<listitem>
|
||||
|
@ -1822,8 +1822,9 @@ GRANT SELECT ON phone_number TO secretary;
|
||||
<para>
|
||||
Note that while views can be used to hide the contents of certain
|
||||
columns using the technique shown above, they cannot be used to reliably
|
||||
conceal the data in unseen rows. For example, the following view is
|
||||
insecure:
|
||||
conceal the data in unseen rows unless the
|
||||
<literal>security_barrier</literal> flag has been set. For example,
|
||||
the following view is insecure:
|
||||
<programlisting>
|
||||
CREATE VIEW phone_number AS
|
||||
SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
|
||||
@ -1870,6 +1871,40 @@ SELECT * FROM phone_number WHERE tricky(person, phone);
|
||||
which references <literal>shoelace_log</> is an unqualified
|
||||
<literal>INSERT</>. 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 invoked on rows until afterthe 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>
|
||||
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
|
||||
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 runtime 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 the runtime of the plan; or even, since they are also reflected in
|
||||
the optimizer statistics, the choice of plan). If these types of "covert
|
||||
channel" attacks are of concern, it is probably unwise to grant any access
|
||||
to the data at all.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="rules-status">
|
||||
|
Reference in New Issue
Block a user