暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

解读2017-08-10发布的几个安全漏洞

digoal 2016-08-15
598

作者

digoal

日期

2016-08-15

标签

PostgreSQL , 安全漏洞 , CVE-2017-7546 , CVE-2017-7547 , CVE-2017-7548


背景

PostgreSQL 社区于08-10发布了新版本,修复了三个安全漏洞。

https://www.postgresql.org/about/news/1772/

```
CVE-2017-7546:
Empty password accepted in some authentication methods

CVE-2017-7547:
The "pg_user_mappings" catalog view discloses passwords to users lacking server privileges

CVE-2017-7548:
lo_put() function ignores ACLs
```

下面一一进行解读。

CVE-2017-7546 允许空密码登陆漏洞

注意,libpq接口的客户端,都会自动拒绝空密码的用户登陆,这个行为可能误导用户认为空密码就是不允许登陆的。

而实际上并非如此,其他客户端驱动可能允许空密码登陆,这个漏洞修复了这个问题。在服务端拒绝空密码的用户登陆。

所以你如果不使用空密码,就不会有这个问题。

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bf6b9e94445610a3d84cf9521032fab993f96fd6

```
Don't allow logging in with empty password.

Some authentication methods allowed it, others did not. In the client-side,
libpq does not even try to authenticate with an empty password, which makes
using empty passwords hazardous: an administrator might think that an
account with an empty password cannot be used to log in, because psql
doesn't allow it, and not realize that a different client would in fact
allow it. To clear that confusion and to be be consistent, disallow empty
passwords in all authentication methods.

All the authentication methods that used plaintext authentication over the
wire, except for BSD authentication, already checked that the password
received from the user was not empty. To avoid forgetting it in the future
again, move the check to the recv_password_packet function. That only
forbids using an empty password with plaintext authentication, however.
MD5 and SCRAM need a different fix:

  • In stable branches, check that the MD5 hash stored for the user does not
    not correspond to an empty string. This adds some overhead to MD5
    authentication, because the server needs to compute an extra MD5 hash, but
    it is not noticeable in practice.

  • In HEAD, modify CREATE and ALTER ROLE to clear the password if an empty
    string, or a password hash that corresponds to an empty string, is
    specified. The user-visible behavior is the same as in the stable branches,
    the user cannot log in, but it seems better to stop the empty password from
    entering the system in the first place. Secondly, it is fairly expensive to
    check that a SCRAM hash doesn't correspond to an empty string, because
    computing a SCRAM hash is much more expensive than an MD5 hash by design,
    so better avoid doing that on every authentication.

We could clear the password on CREATE/ALTER ROLE also in stable branches,
but we would still need to check at authentication time, because even if we
prevent empty passwords from being stored in pg_authid, there might be
existing ones there already.

Reported by Jeroen van der Ham, Ben de Graaff and Jelte Fennema.

Security: CVE-2017-7546
```

CVE-2017-7547 允许未授予USAGE权限的用户读取foreign server配置

这个漏洞和foreign server有关,通常某个用户u1要使用FOREIGN SERVER需要分为几个步骤。

1、创建foreign server S1,里面包含SERVER的连接信息。

2、赋予foreign server S1的usage权限给某个用户u1。(本漏洞所在。)

3、基于这个foreign server S1创建u1的user mapping,里面包含登陆这个foreign server的信息。

4、现在u1可以基于这个foreign server S1创建外部表。

现在的漏洞是,没有操作第2步,普通用户u1可以查询pg_user_mapping表,得到登陆这个foreign server的信息(例如连接这个外部server的用户和密码)。

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=e568e1eee4650227170cf8c64eedb74bafd7d1f0

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=3eefc51053f250837c3115c12f8119d16881a2d7

```
Again match pg_user_mappings to information_schema.user_mapping_options.

Commit 3eefc51053f250837c3115c12f8119d16881a2d7 claimed to make
pg_user_mappings enforce the qualifications user_mapping_options had
been enforcing, but its removal of a longstanding restriction left them
distinct when the current user is the subject of a mapping yet has no
server privileges. user_mapping_options emits no rows for such a
mapping, but pg_user_mappings includes full umoptions. Change
pg_user_mappings to show null for umoptions. Back-patch to 9.2, like
the above commit.

Reviewed by Tom Lane. Reported by Jeff Janes.

Security: CVE-2017-7547
```

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blobdiff;f=src/test/regress/expected/foreign_data.out;h=927d0189a0c26c5875cbe5af44d71d3819bd34eb;hp=7f2f529393d6682a69702cb32d3975074b97f87d;hb=e568e1eee4650227170cf8c64eedb74bafd7d1f0;hpb=bf6b9e94445610a3d84cf9521032fab993f96fd6

已修复后,例子

```
-GRANT USAGE ON FOREIGN SERVER s10 TO regress_unprivileged_role;
--- owner of server can see option fields
+CREATE USER MAPPING FOR regress_unprivileged_role SERVER s10 OPTIONS (user 'secret');

+-- unprivileged user cannot see any option field
SET ROLE regress_unprivileged_role;
\deu+
List of user mappings
Server | User name | FDW options
--------+---------------------------+-------------
s10 | public |
+ s10 | regress_unprivileged_role | -- 未修复时,这里会显示user 'secret'
s4 | regress_foreign_data_user |
s5 | regress_test_role |
s6 | regress_test_role |
```

老版本要修复这个问题,请参考 https://www.postgresql.org/about/news/1772/ ,需要修改系统表的信息。

所以,如果你继续使用老版本,你要回收某个用户的foreign server权限,请同时删除user mapping。就不会有问题。

CVE-2017-7548 大对象操作函数lo_put()未检测写权限

漏洞描述:

在没有某个大对象的UPDATE权限时,用户依旧可以使用lo_put()函数操作这个大对象。

修复后,需要赋予这个大对象UPDATE权限,才可以调用lo_put()操作这个大对象。

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8d9881911f0d30e0783a6bb1363b94a2c817433d

```
Require update permission for the large object written by lo_put().

lo_put() surely should require UPDATE permission, the same as lowrite(),
but it failed to check for that, as reported by Chapman Flack. Oversight
in commit c50b7c09d; backpatch to 9.4 where that was introduced.

Tom Lane and Michael Paquier

Security: CVE-2017-7548
```

修复后的例子如下

src/test/regress/expected/privileges.out

```
SET SESSION AUTHORIZATION regress_user1;
1186 SELECT lo_create(1001);
1187 lo_create
1188 -----------
1189 1001
1190 (1 row)
1191
1192 SELECT lo_create(1002);
1193 lo_create
1194 -----------
1195 1002
1196 (1 row)
1197

1216 GRANT ALL ON LARGE OBJECT 1001 TO PUBLIC;
1217 GRANT SELECT ON LARGE OBJECT 1003 TO regress_user2;
1218 GRANT SELECT,UPDATE ON LARGE OBJECT 1004 TO regress_user2;
1219 GRANT ALL ON LARGE OBJECT 1005 TO regress_user2;
1220 GRANT SELECT ON LARGE OBJECT 1005 TO regress_user2 WITH GRANT OPTION;
1221 GRANT SELECT, INSERT ON LARGE OBJECT 1001 TO PUBLIC; -- to be failed
1222 ERROR: invalid privilege type INSERT for large object
1223 GRANT SELECT, UPDATE ON LARGE OBJECT 1001 TO nosuchuser; -- to be failed
1224 ERROR: role "nosuchuser" does not exist
1225 GRANT SELECT, UPDATE ON LARGE OBJECT 999 TO PUBLIC; -- to be failed
1226 ERROR: large object 999 does not exist
1227 \c -

1228 SET SESSION AUTHORIZATION regress_user2;

1299 -- confirm ACL setting
1300 SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
1301 oid | ownername | lomacl
1302 ------+---------------+------------------------------------------------------------------------------------------------
1303 1001 | regress_user1 | {regress_user1=rw/regress_user1,=rw/regress_user1}
1304 1002 | regress_user1 |
1305 1003 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r/regress_user1}
1306 1004 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=rw/regress_user1}
1307 1005 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r*w/regress_user1,regress_user3=r/regress_user2}
1308 2001 | regress_user2 | {regress_user2=rw/regress_user2,regress_user3=rw/regress_user2}
1309 (6 rows)

+SELECT loread(lo_open(1001, x'20000'::int), 32); -- allowed, for now
+ loread
+--------
+ \x
+(1 row)
+
+SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); -- fail, wrong mode
+ERROR: large object descriptor 0 was not opened for writing

+SELECT lo_put(1002, 1, 'abcd'); -- to be denied
+ERROR: permission denied for large object 1002
```

PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

9.9元购买3个月阿里云RDS PostgreSQL实例

PostgreSQL 解决方案集合

德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat

文章转载自digoal,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论