Skip to content

Commit cc4371d

Browse files
committed
Document search_path security with untrusted dbowner or CREATEROLE.
Commit 5770172 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
1 parent ba62bb6 commit cc4371d

File tree

1 file changed

+40
-40
lines changed

1 file changed

+40
-40
lines changed

doc/src/sgml/ddl.sgml

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3007,67 +3007,67 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
30073007
<title>Usage Patterns</title>
30083008

30093009
<para>
3010-
Schemas can be used to organize your data in many ways. There are a few
3011-
usage patterns easily supported by the default configuration, only one of
3012-
which suffices when database users mistrust other database users:
3010+
Schemas can be used to organize your data in many ways.
3011+
A <firstterm>secure schema usage pattern</firstterm> prevents untrusted
3012+
users from changing the behavior of other users' queries. When a database
3013+
does not use a secure schema usage pattern, users wishing to securely
3014+
query that database would take protective action at the beginning of each
3015+
session. Specifically, they would begin each session by
3016+
setting <varname>search_path</varname> to the empty string or otherwise
3017+
removing non-superuser-writable schemas
3018+
from <varname>search_path</varname>. There are a few usage patterns
3019+
easily supported by the default configuration:
30133020
<itemizedlist>
30143021
<listitem>
30153022
<!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump
3016-
doesn't preserve that DROP. -->
3023+
doesn't preserve that DROP.
3024+
3025+
A database owner can attack the database's users via "CREATE SCHEMA
3026+
trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A
3027+
CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the
3028+
database owner attack. -->
30173029
<para>
30183030
Constrain ordinary users to user-private schemas. To implement this,
30193031
issue <literal>REVOKE CREATE ON SCHEMA public FROM PUBLIC</literal>,
3020-
and create a schema for each user with the same name as that user. If
3021-
affected users had logged in before this, consider auditing the public
3032+
and create a schema for each user with the same name as that user.
3033+
Recall that the default search path starts
3034+
with <literal>$user</literal>, which resolves to the user name.
3035+
Therefore, if each user has a separate schema, they access their own
3036+
schemas by default. After adopting this pattern in a database where
3037+
untrusted users had already logged in, consider auditing the public
30223038
schema for objects named like objects in
3023-
schema <literal>pg_catalog</literal>. Recall that the default search
3024-
path starts with <literal>$user</literal>, which resolves to the user
3025-
name. Therefore, if each user has a separate schema, they access their
3026-
own schemas by default.
3039+
schema <literal>pg_catalog</literal>. This pattern is a secure schema
3040+
usage pattern unless an untrusted user is the database owner or holds
3041+
the <literal>CREATEROLE</literal> privilege, in which case no secure
3042+
schema usage pattern exists.
30273043
</para>
3028-
</listitem>
3029-
3030-
<listitem>
30313044
<para>
3032-
Remove the public schema from each user's default search path
3033-
using <literal>ALTER ROLE <replaceable>user</replaceable> SET
3034-
search_path = "$user"</literal>. Everyone retains the ability to
3035-
create objects in the public schema, but only qualified names will
3036-
choose those objects. While qualified table references are fine, calls
3037-
to functions in the public schema <link linkend="typeconv-func">will be
3038-
unsafe or unreliable</link>. Also, a user holding
3039-
the <literal>CREATEROLE</literal> privilege can undo this setting and
3040-
issue arbitrary queries under the identity of users relying on the
3041-
setting. If you create functions or extensions in the public schema or
3042-
grant <literal>CREATEROLE</literal> to users not warranting this
3043-
almost-superuser ability, use the first pattern instead.
30443045
</para>
30453046
</listitem>
30463047

30473048
<listitem>
30483049
<para>
3049-
Remove the public schema from <varname>search_path</varname> in
3050-
<link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>.
3051-
The ensuing user experience matches the previous pattern. In addition
3052-
to that pattern's implications for functions
3053-
and <literal>CREATEROLE</literal>, this trusts database owners
3054-
like <literal>CREATEROLE</literal>. If you create functions or
3055-
extensions in the public schema or assign
3056-
the <literal>CREATEROLE</literal>
3057-
privilege, <literal>CREATEDB</literal> privilege or individual database
3058-
ownership to users not warranting almost-superuser access, use the
3059-
first pattern instead.
3050+
Remove the public schema from the default search path, by modifying
3051+
<link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>
3052+
or by issuing <literal>ALTER ROLE ALL SET search_path =
3053+
"$user"</literal>. Everyone retains the ability to create objects in
3054+
the public schema, but only qualified names will choose those objects.
3055+
While qualified table references are fine, calls to functions in the
3056+
public schema <link linkend="typeconv-func">will be unsafe or
3057+
unreliable</link>. If you create functions or extensions in the public
3058+
schema, use the first pattern instead. Otherwise, like the first
3059+
pattern, this is secure unless an untrusted user is the database owner
3060+
or holds the <literal>CREATEROLE</literal> privilege.
30603061
</para>
30613062
</listitem>
30623063

30633064
<listitem>
30643065
<para>
30653066
Keep the default. All users access the public schema implicitly. This
30663067
simulates the situation where schemas are not available at all, giving
3067-
a smooth transition from the non-schema-aware world. However, any user
3068-
can issue arbitrary queries under the identity of any user not electing
3069-
to protect itself individually. This pattern is acceptable only when
3070-
the database has a single user or a few mutually-trusting users.
3068+
a smooth transition from the non-schema-aware world. However, this is
3069+
never a secure pattern. It is acceptable only when the database has a
3070+
single user or a few mutually-trusting users.
30713071
</para>
30723072
</listitem>
30733073
</itemizedlist>

0 commit comments

Comments
 (0)