@@ -3010,67 +3010,67 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
30103010 <title>Usage Patterns</title>
30113011
30123012 <para>
3013- Schemas can be used to organize your data in many ways. There are a few
3014- usage patterns easily supported by the default configuration, only one of
3015- which suffices when database users mistrust other database users:
3013+ Schemas can be used to organize your data in many ways.
3014+ A <firstterm>secure schema usage pattern</firstterm> prevents untrusted
3015+ users from changing the behavior of other users' queries. When a database
3016+ does not use a secure schema usage pattern, users wishing to securely
3017+ query that database would take protective action at the beginning of each
3018+ session. Specifically, they would begin each session by
3019+ setting <varname>search_path</varname> to the empty string or otherwise
3020+ removing non-superuser-writable schemas
3021+ from <varname>search_path</varname>. There are a few usage patterns
3022+ easily supported by the default configuration:
30163023 <itemizedlist>
30173024 <listitem>
30183025 <!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump
3019- doesn't preserve that DROP. -->
3026+ doesn't preserve that DROP.
3027+
3028+ A database owner can attack the database's users via "CREATE SCHEMA
3029+ trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A
3030+ CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the
3031+ database owner attack. -->
30203032 <para>
30213033 Constrain ordinary users to user-private schemas. To implement this,
30223034 issue <literal>REVOKE CREATE ON SCHEMA public FROM PUBLIC</literal>,
3023- and create a schema for each user with the same name as that user. If
3024- affected users had logged in before this, consider auditing the public
3035+ and create a schema for each user with the same name as that user.
3036+ Recall that the default search path starts
3037+ with <literal>$user</literal>, which resolves to the user name.
3038+ Therefore, if each user has a separate schema, they access their own
3039+ schemas by default. After adopting this pattern in a database where
3040+ untrusted users had already logged in, consider auditing the public
30253041 schema for objects named like objects in
3026- schema <literal>pg_catalog</literal>. Recall that the default search
3027- path starts with <literal>$user</literal>, which resolves to the user
3028- name. Therefore, if each user has a separate schema, they access their
3029- own schemas by default .
3042+ schema <literal>pg_catalog</literal>. This pattern is a secure schema
3043+ usage pattern unless an untrusted user is the database owner or holds
3044+ the <literal>CREATEROLE</literal> privilege, in which case no secure
3045+ schema usage pattern exists .
30303046 </para>
3031- </listitem>
3032-
3033- <listitem>
30343047 <para>
3035- Remove the public schema from each user's default search path
3036- using <literal>ALTER ROLE <replaceable>user</replaceable> SET
3037- search_path = "$user"</literal>. Everyone retains the ability to
3038- create objects in the public schema, but only qualified names will
3039- choose those objects. While qualified table references are fine, calls
3040- to functions in the public schema <link linkend="typeconv-func">will be
3041- unsafe or unreliable</link>. Also, a user holding
3042- the <literal>CREATEROLE</literal> privilege can undo this setting and
3043- issue arbitrary queries under the identity of users relying on the
3044- setting. If you create functions or extensions in the public schema or
3045- grant <literal>CREATEROLE</literal> to users not warranting this
3046- almost-superuser ability, use the first pattern instead.
30473048 </para>
30483049 </listitem>
30493050
30503051 <listitem>
30513052 <para>
3052- Remove the public schema from <varname>search_path</varname> in
3053- <link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>.
3054- The ensuing user experience matches the previous pattern. In addition
3055- to that pattern's implications for functions
3056- and <literal>CREATEROLE</literal>, this trusts database owners
3057- like <literal>CREATEROLE</literal>. If you create functions or
3058- extensions in the public schema or assign
3059- the <literal>CREATEROLE</literal>
3060- privilege, <literal>CREATEDB</literal> privilege or individual database
3061- ownership to users not warranting almost-superuser access, use the
3062- first pattern instead .
3053+ Remove the public schema from the default search path, by modifying
3054+ <link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>
3055+ or by issuing <literal>ALTER ROLE ALL SET search_path =
3056+ "$user"</literal>. Everyone retains the ability to create objects in
3057+ the public schema, but only qualified names will choose those objects.
3058+ While qualified table references are fine, calls to functions in the
3059+ public schema <link linkend="typeconv-func">will be unsafe or
3060+ unreliable</link>. If you create functions or extensions in the public
3061+ schema, use the first pattern instead. Otherwise, like the first
3062+ pattern, this is secure unless an untrusted user is the database owner
3063+ or holds the <literal>CREATEROLE</literal> privilege .
30633064 </para>
30643065 </listitem>
30653066
30663067 <listitem>
30673068 <para>
30683069 Keep the default. All users access the public schema implicitly. This
30693070 simulates the situation where schemas are not available at all, giving
3070- a smooth transition from the non-schema-aware world. However, any user
3071- can issue arbitrary queries under the identity of any user not electing
3072- to protect itself individually. This pattern is acceptable only when
3073- the database has a single user or a few mutually-trusting users.
3071+ a smooth transition from the non-schema-aware world. However, this is
3072+ never a secure pattern. It is acceptable only when the database has a
3073+ single user or a few mutually-trusting users.
30743074 </para>
30753075 </listitem>
30763076 </itemizedlist>
0 commit comments