mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Document search_path security with untrusted dbowner or CREATEROLE.
Commit 5770172cb0c9df9e6ce27c507b449557e5b45124 wrote, incorrectly, that certain schema usage patterns are secure against CREATEROLE users and database owners. When an untrusted user is the database owner or holds CREATEROLE privilege, a query is secure only if its session started with SELECT pg_catalog.set_config('search_path', '', false) or equivalent. Back-patch to 9.4 (all supported versions). Discussion: https://postgr.es/m/20191013013512.GC4131753@rfd.leadboat.com
This commit is contained in:
parent
ba62bb63b3
commit
cc4371dc34
@ -3007,56 +3007,57 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
|
||||
<title>Usage Patterns</title>
|
||||
|
||||
<para>
|
||||
Schemas can be used to organize your data in many ways. There are a few
|
||||
usage patterns easily supported by the default configuration, only one of
|
||||
which suffices when database users mistrust other database users:
|
||||
Schemas can be used to organize your data in many ways.
|
||||
A <firstterm>secure schema usage pattern</firstterm> prevents untrusted
|
||||
users from changing the behavior of other users' queries. When a database
|
||||
does not use a secure schema usage pattern, users wishing to securely
|
||||
query that database would take protective action at the beginning of each
|
||||
session. Specifically, they would begin each session by
|
||||
setting <varname>search_path</varname> to the empty string or otherwise
|
||||
removing non-superuser-writable schemas
|
||||
from <varname>search_path</varname>. There are a few usage patterns
|
||||
easily supported by the default configuration:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump
|
||||
doesn't preserve that DROP. -->
|
||||
doesn't preserve that DROP.
|
||||
|
||||
A database owner can attack the database's users via "CREATE SCHEMA
|
||||
trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A
|
||||
CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the
|
||||
database owner attack. -->
|
||||
<para>
|
||||
Constrain ordinary users to user-private schemas. To implement this,
|
||||
issue <literal>REVOKE CREATE ON SCHEMA public FROM PUBLIC</literal>,
|
||||
and create a schema for each user with the same name as that user. If
|
||||
affected users had logged in before this, consider auditing the public
|
||||
and create a schema for each user with the same name as that user.
|
||||
Recall that the default search path starts
|
||||
with <literal>$user</literal>, which resolves to the user name.
|
||||
Therefore, if each user has a separate schema, they access their own
|
||||
schemas by default. After adopting this pattern in a database where
|
||||
untrusted users had already logged in, consider auditing the public
|
||||
schema for objects named like objects in
|
||||
schema <literal>pg_catalog</literal>. Recall that the default search
|
||||
path starts with <literal>$user</literal>, which resolves to the user
|
||||
name. Therefore, if each user has a separate schema, they access their
|
||||
own schemas by default.
|
||||
schema <literal>pg_catalog</literal>. This pattern is a secure schema
|
||||
usage pattern unless an untrusted user is the database owner or holds
|
||||
the <literal>CREATEROLE</literal> privilege, in which case no secure
|
||||
schema usage pattern exists.
|
||||
</para>
|
||||
<para>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Remove the public schema from each user's default search path
|
||||
using <literal>ALTER ROLE <replaceable>user</replaceable> SET
|
||||
search_path = "$user"</literal>. Everyone retains the ability to
|
||||
create objects in the public schema, but only qualified names will
|
||||
choose those objects. While qualified table references are fine, calls
|
||||
to functions in the public schema <link linkend="typeconv-func">will be
|
||||
unsafe or unreliable</link>. Also, a user holding
|
||||
the <literal>CREATEROLE</literal> privilege can undo this setting and
|
||||
issue arbitrary queries under the identity of users relying on the
|
||||
setting. If you create functions or extensions in the public schema or
|
||||
grant <literal>CREATEROLE</literal> to users not warranting this
|
||||
almost-superuser ability, use the first pattern instead.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Remove the public schema from <varname>search_path</varname> in
|
||||
<link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>.
|
||||
The ensuing user experience matches the previous pattern. In addition
|
||||
to that pattern's implications for functions
|
||||
and <literal>CREATEROLE</literal>, this trusts database owners
|
||||
like <literal>CREATEROLE</literal>. If you create functions or
|
||||
extensions in the public schema or assign
|
||||
the <literal>CREATEROLE</literal>
|
||||
privilege, <literal>CREATEDB</literal> privilege or individual database
|
||||
ownership to users not warranting almost-superuser access, use the
|
||||
first pattern instead.
|
||||
Remove the public schema from the default search path, by modifying
|
||||
<link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>
|
||||
or by issuing <literal>ALTER ROLE ALL SET search_path =
|
||||
"$user"</literal>. Everyone retains the ability to create objects in
|
||||
the public schema, but only qualified names will choose those objects.
|
||||
While qualified table references are fine, calls to functions in the
|
||||
public schema <link linkend="typeconv-func">will be unsafe or
|
||||
unreliable</link>. If you create functions or extensions in the public
|
||||
schema, use the first pattern instead. Otherwise, like the first
|
||||
pattern, this is secure unless an untrusted user is the database owner
|
||||
or holds the <literal>CREATEROLE</literal> privilege.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
@ -3064,10 +3065,9 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
|
||||
<para>
|
||||
Keep the default. All users access the public schema implicitly. This
|
||||
simulates the situation where schemas are not available at all, giving
|
||||
a smooth transition from the non-schema-aware world. However, any user
|
||||
can issue arbitrary queries under the identity of any user not electing
|
||||
to protect itself individually. This pattern is acceptable only when
|
||||
the database has a single user or a few mutually-trusting users.
|
||||
a smooth transition from the non-schema-aware world. However, this is
|
||||
never a secure pattern. It is acceptable only when the database has a
|
||||
single user or a few mutually-trusting users.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
Loading…
x
Reference in New Issue
Block a user