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:
@ -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>
|
||||||
|
Reference in New Issue
Block a user