1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Doc: word-smith the discussion of secure schema usage patterns.

Rearrange the discussion of user-private schemas so that details
applying only to upgraded-from-pre-v15 databases are in a follow-on
paragraph, not in the main description of how to set up this pattern.
This seems a little clearer even today, and it'll get more so as
pre-v15 systems fade into the sunset.

Wording contributions from Robert Haas, Tom Lane, Noah Misch.

Discussion: https://postgr.es/m/CA+TgmoYUHsfp90inEMAP0yNr7Y_L6EphPH1YOon1JKtBztXHyQ@mail.gmail.com
This commit is contained in:
Tom Lane
2022-12-01 12:10:25 -05:00
parent a711b36e5b
commit afa4a4f764

View File

@ -3182,40 +3182,43 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
query that database would take protective action at the beginning of each query that database would take protective action at the beginning of each
session. Specifically, they would begin each session by session. Specifically, they would begin each session by
setting <varname>search_path</varname> to the empty string or otherwise setting <varname>search_path</varname> to the empty string or otherwise
removing non-superuser-writable schemas removing schemas that are writable by non-superusers
from <varname>search_path</varname>. There are a few usage patterns from <varname>search_path</varname>. There are a few usage patterns
easily supported by the default configuration: easily supported by the default configuration:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump <para>
doesn't preserve that DROP. Constrain ordinary users to user-private schemas.
To implement this pattern, first ensure that no schemas have
A database owner can attack the database's users via "CREATE SCHEMA public <literal>CREATE</literal> privileges. Then, for every user
needing to create non-temporary objects, create a schema with the
same name as that user, for example
<literal>CREATE SCHEMA alice AUTHORIZATION alice</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.) 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>
<!-- A database owner can attack the database's users via "CREATE SCHEMA
trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A
CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the
database owner attack. --> database owner attack. -->
<para> <para>
Constrain ordinary users to user-private schemas. To implement this, In <productname>PostgreSQL</productname> 15 and later, the default
first issue <literal>REVOKE CREATE ON SCHEMA public FROM configuration supports this usage pattern. In prior versions, or
PUBLIC</literal>. Then, for every user needing to create non-temporary when using a database that has been upgraded from a prior version,
objects, create a schema with the same name as that user. Recall that you will need to remove the public <literal>CREATE</literal>
the default search path starts with <literal>$user</literal>, which privilege from the <literal>public</literal> schema (issue
resolves to the user name. Therefore, if each user has a separate <literal>REVOKE CREATE ON SCHEMA public FROM PUBLIC</literal>).
schema, they access their own schemas by default. After adopting this Then consider auditing the <literal>public</literal> schema for
pattern in a database where untrusted users had already logged in, objects named like objects in schema <literal>pg_catalog</literal>.
consider auditing the public schema for objects named like objects in
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>
If the database originated in an upgrade
from <productname>PostgreSQL</productname> 14 or earlier,
the <literal>REVOKE</literal> is essential. Otherwise, the default
configuration follows this pattern; ordinary users can create only
temporary objects until a privileged user furnishes a schema.
</para> </para>
<!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump
doesn't preserve that DROP. -->
</listitem> </listitem>
<listitem> <listitem>