diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 56a7860078..7dbdca6074 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -2390,56 +2390,57 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC; Usage Patterns - Schemas can be used to organize your data in many ways. There are a few - usage patterns easily supported by the default configuration, only one of - which suffices when database users mistrust other database users: + Schemas can be used to organize your data in many ways. + A secure schema usage pattern prevents untrusted + users from changing the behavior of other users' queries. When a database + does not use a secure schema usage pattern, users wishing to securely + query that database would take protective action at the beginning of each + session. Specifically, they would begin each session by + setting search_path to the empty string or otherwise + removing non-superuser-writable schemas + from search_path. There are a few usage patterns + easily supported by the default configuration: + doesn't preserve that DROP. + + A database owner can attack the database's users via "CREATE SCHEMA + trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A + CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the + database owner attack. --> Constrain ordinary users to user-private schemas. To implement this, issue REVOKE CREATE ON SCHEMA public FROM PUBLIC, - and create a schema for each user with the same name as that user. If - affected users had logged in before this, consider auditing the public + and create a schema for each user with the same name as that user. + Recall that the default search path starts + with $user, which resolves to the user name. + Therefore, if each user has a separate schema, they access their own + schemas by default. After adopting this pattern in a database where + untrusted users had already logged in, consider auditing the public schema for objects named like objects in - schema pg_catalog. Recall that the default search - path starts with $user, which resolves to the user - name. Therefore, if each user has a separate schema, they access their - own schemas by default. + schema pg_catalog. This pattern is a secure schema + usage pattern unless an untrusted user is the database owner or holds + the CREATEROLE privilege, in which case no secure + schema usage pattern exists. + + - Remove the public schema from each user's default search path - using ALTER ROLE user SET - search_path = "$user". Everyone retains the ability to - create objects in the public schema, but only qualified names will - choose those objects. While qualified table references are fine, calls - to functions in the public schema will be - unsafe or unreliable. Also, a user holding - the CREATEROLE privilege can undo this setting and - issue arbitrary queries under the identity of users relying on the - setting. If you create functions or extensions in the public schema or - grant CREATEROLE to users not warranting this - almost-superuser ability, use the first pattern instead. - - - - - - Remove the public schema from search_path in - postgresql.conf. - The ensuing user experience matches the previous pattern. In addition - to that pattern's implications for functions - and CREATEROLE, this trusts database owners - like CREATEROLE. If you create functions or - extensions in the public schema or assign - the CREATEROLE - privilege, CREATEDB privilege or individual database - ownership to users not warranting almost-superuser access, use the - first pattern instead. + Remove the public schema from the default search path, by modifying + postgresql.conf + or by issuing ALTER ROLE ALL SET search_path = + "$user". Everyone retains the ability to create objects in + the public schema, but only qualified names will choose those objects. + While qualified table references are fine, calls to functions in the + public schema will be unsafe or + unreliable. If you create functions or extensions in the public + schema, use the first pattern instead. Otherwise, like the first + pattern, this is secure unless an untrusted user is the database owner + or holds the CREATEROLE privilege. @@ -2447,10 +2448,9 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC; Keep the default. All users access the public schema implicitly. This simulates the situation where schemas are not available at all, giving - a smooth transition from the non-schema-aware world. However, any user - can issue arbitrary queries under the identity of any user not electing - to protect itself individually. This pattern is acceptable only when - the database has a single user or a few mutually-trusting users. + a smooth transition from the non-schema-aware world. However, this is + never a secure pattern. It is acceptable only when the database has a + single user or a few mutually-trusting users.