@@ -3007,67 +3007,67 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
3007
3007
<title>Usage Patterns</title>
3008
3008
3009
3009
<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:
3013
3020
<itemizedlist>
3014
3021
<listitem>
3015
3022
<!-- "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. -->
3017
3029
<para>
3018
3030
Constrain ordinary users to user-private schemas. To implement this,
3019
3031
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
3022
3038
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 .
3027
3043
</para>
3028
- </listitem>
3029
-
3030
- <listitem>
3031
3044
<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.
3044
3045
</para>
3045
3046
</listitem>
3046
3047
3047
3048
<listitem>
3048
3049
<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 .
3060
3061
</para>
3061
3062
</listitem>
3062
3063
3063
3064
<listitem>
3064
3065
<para>
3065
3066
Keep the default. All users access the public schema implicitly. This
3066
3067
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.
3071
3071
</para>
3072
3072
</listitem>
3073
3073
</itemizedlist>
0 commit comments