Обсуждение: BUG #15371: a user who not a member of pg_read_server_files role cancreate a new user into pg_read_server_files

Поиск
Список
Период
Сортировка

BUG #15371: a user who not a member of pg_read_server_files role cancreate a new user into pg_read_server_files

От
PG Bug reporting form
Дата:
The following bug has been logged on the website:

Bug reference:      15371
Logged by:          zhou xiaowei
Email address:      110876189@qq.com
PostgreSQL version: 11beta2
Operating system:   linux
Description:

my test step:
1,execute "CREATE USER mytestuser WITH PASSWORD '12345678'  CREATEDB
CREATEROLE;" use a supper user;
2,use mytestuser to login, and then execute "copy mytestuser_t from
'/data/dev_zxw/PGcore/src/copy1.sql';". I got "ERROR:  must be superuser or
a member of the pg_read_server_files role to COPY from a file", this result
is OK. contine to execute "create user mytestuser1 with password '12345678'
in role pg_read_server_files;". I got a success result ,which is
unexpected.
3, use  mytestuser1 login again, I execute "copy mytestuser_t1 from
'/data/dev_zxw/PGcore/src/copy1.sql';" successfully. this result is
unexpected.

the details:
[  src]$ psql postgres -p54xx
psql (11beta2)
Type "help" for help.
postgres=# CREATE USER mytestuser WITH PASSWORD '12345678'  CREATEDB
CREATEROLE;
CREATE ROLE
postgres=# \q

[  src]$ psql postgres -h10.21.x.x -p54xx -Umytestuser
Password for user mytestuser:
psql (11beta2)
Type "help" for help.
postgres=> create table mytestuser_t(f int,f1 int);
CREATE TABLE
postgres=> copy mytestuser_t from '/data/dev_zxw/PGcore/src/copy1.sql';
ERROR:  must be superuser or a member of the pg_read_server_files role to
COPY from a file
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also
works for anyone.
postgres=> create user mytestuser1 with password '12345678' in role
pg_read_server_files;
CREATE ROLE
postgres=> \q

[  src]$ psql postgres -h10.21.x.x -p54xx -Umytestuser1
Password for user mytestuser1:
psql (11beta2)
Type "help" for help.
postgres=> create table mytestuser_t1(f int,f1 int);
CREATE TABLE
postgres=> copy mytestuser_t1 from '/data/dev_zxw/PGcore/src/copy1.sql';
COPY 1
postgres=>
postgres=> select * from mytestuser_t1;
 f | f1
---+----
 2 |  4
(1 row)

see the code src/backend/commands/user.c, the check privillige code is :
static void
AddRoleMems(const char *rolename, Oid roleid,
            List *memberSpecs, List *memberIds,
            Oid grantorId, bool admin_opt)
{
    else
    {
        if (!have_createrole_privilege() &&
            !is_admin_of_role(grantorId, roleid))
            ereport(ERROR,
                    (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                     errmsg("must have admin option on role \"%s\"",
                            rolename)));
    }

I think the line "if (!have_createrole_privilege() &&
!is_admin_of_role(grantorId, roleid))" should been modifed to "if
(!have_createrole_privilege() || !is_admin_of_role(grantorId, roleid))" .

am I right or not?
Thanks!


Re: BUG #15371: a user who not a member of pg_read_server_files rolecan create a new user into pg_read_server_files

От
"David G. Johnston"
Дата:
On Saturday, September 8, 2018, PG Bug reporting form <noreply@postgresql.org> wrote:

see the code src/backend/commands/user.c, the check privillige code is :
static void
AddRoleMems(const char *rolename, Oid roleid,
                        List *memberSpecs, List *memberIds,
                        Oid grantorId, bool admin_opt)
{
        else
        {
                if (!have_createrole_privilege() &&
                        !is_admin_of_role(grantorId, roleid))
                        ereport(ERROR,
                                        (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                         errmsg("must have admin option on role \"%s\"",
                                                        rolename)));
        }

I think the line "if (!have_createrole_privilege() &&
!is_admin_of_role(grantorId, roleid))" should been modifed to "if
(!have_createrole_privilege() || !is_admin_of_role(grantorId, roleid))" .

Security code would ideally be written so not erroring requires an actual matched condition while leaving the default to be an error.  So, I think, the && is ok, remove both negations, put a commented no-op there, and move the error to an else block.

Whether that is sufficient for this bug I do not know, but it would be a more secure format.

David J.

Re: BUG #15371: a user who not a member of pg_read_server_files rolecan create a new user into pg_read_server_files

От
"David G. Johnston"
Дата:
On Saturday, September 8, 2018, PG Bug reporting form <noreply@postgresql.org> wrote:

1,execute "CREATE USER mytestuser WITH PASSWORD '12345678'  CREATEDB
CREATEROLE;" use a supper user;

So, reading the create role docs this seems to be working as designed.

“ Be careful with the CREATEROLE privilege. There is no concept of inheritance for the privileges of a CREATEROLE-role. That means that even if a role does not have a certain privilege but is allowed to create other roles, it can easily create another role with different privileges than its own (except for creating roles with superuser privileges)“

David J.