2017-08-10 安全更新发布

由 PostgreSQL 全球开发组发布于 2017-08-10

PostgreSQL 全球开发组已发布了我们数据库系统的所有受支持版本的更新,包括 9.6.4、9.5.8、9.4.13、9.3.18 和 9.2.22。此版本修复了三个安全问题。它还修补了过去三个月报告的 50 多个其他错误。受以下安全问题影响的用户应尽快更新。受 CVE-2017-7547 影响的用户需要在升级后执行其他步骤来解决此问题。其他用户应计划在下次方便的停机时间内更新。

安全问题

此版本已修复三个安全漏洞

  • CVE-2017-7546:在某些身份验证方法中接受空密码
  • CVE-2017-7547:"pg_user_mappings" 目录视图向缺乏服务器权限的用户泄露密码
  • CVE-2017-7548:lo_put() 函数忽略 ACL

CVE-2017-7546:在某些身份验证方法中接受空密码

libpq,以及任何使用 libpq 的连接驱动程序,都会忽略空密码,并且不会将它们传输到服务器。当使用 libpq 或基于 libpq 的连接驱动程序执行基于密码的身份验证方法时,设置空密码似乎等同于禁用密码登录。但是,使用非基于 libpq 的连接驱动程序可能会允许具有空密码的客户端登录。

为了解决此问题,此更新禁止在任何基于密码的身份验证方法中提交空密码。服务器将拒绝在帐户上设置任何空密码。

CVE-2017-7547:"pg_user_mappings" 目录视图向缺乏服务器权限的用户泄露密码

此修复与外部数据包装器的使用有关,特别是用户映射功能。

在此修复之前,即使用户没有关联外部服务器上的 USAGE 权限,用户也可以访问查看 pg_user_mappings 中的选项。这意味着用户可以看到详细信息,例如服务器管理员而不是用户可能设置的密码。

此修复只会修复使用 initdb 新创建的集群中的行为。要修复现有系统上的此问题,您需要按照以下步骤操作。有关更多详细信息,请参阅发行说明

  1. 在您的 postgresql.conf 文件中,添加以下内容

    allow_system_table_mods = true
    
  2. 添加该行后,您需要重新启动 PostgreSQL 集群。

  3. 在集群的每个数据库中,以超级用户身份运行以下命令

    SET search_path = pg_catalog;
    CREATE OR REPLACE VIEW pg_user_mappings AS
    SELECT
        U.oid       AS umid,
        S.oid       AS srvid,
        S.srvname   AS srvname,
        U.umuser    AS umuser,
        CASE WHEN U.umuser = 0 THEN
            'public'
        ELSE
            A.rolname
        END AS usename,
        CASE WHEN (U.umuser <> 0 AND A.rolname = current_user
                     AND (pg_has_role(S.srvowner, 'USAGE')
                          OR has_server_privilege(S.oid, 'USAGE')))
                    OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE'))
                    OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user)
                    THEN U.umoptions
                 ELSE NULL END AS umoptions
    FROM pg_user_mapping U
    LEFT JOIN pg_authid A ON (A.oid = U.umuser)
    JOIN pg_foreign_server S ON (U.umserver = S.oid);
    
  4. 您还需要在 *template0* 和 *template1* 数据库上运行该命令,否则该漏洞将存在于您将来创建的数据库中。

    首先,您需要允许 *template0* 接受连接。在 PostgreSQL 9.5 中,您可以运行以下命令

    ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true;
    

    在 PostgreSQL 9.4 及更低版本中,您必须运行此命令

    UPDATE pg_database SET datallowconn = true WHERE datname = 'template0';
    

    然后,在您的 *template0* 和 *template1* 数据库中,按照步骤 3 中的描述运行命令

    完成后,您需要禁止从 *template0* 连接。在 PostgreSQL 9.5 中,您可以运行以下命令

    ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false;
    

    在 PostgreSQL 9.4 及更低版本中,您必须运行以下命令

    UPDATE pg_database SET datallowconn = false WHERE datname = 'template0';
    
  5. 从您的 postgresql.conf 文件中删除以下行

    allow_system_table_mods = false
    
  6. 重新启动您的 PostgreSQL 集群

有关更多详细信息,请参阅发行说明

CVE-2017-7548:lo_put() 函数忽略 ACL

lo_put() 函数应要求与 lowrite() 相同的权限,但缺少权限检查,这会允许任何用户更改大型对象中的数据。

为了修复此问题,lo_put() 函数已更改为检查目标对象上的 UPDATE 权限。

错误修复和改进

此更新还修复了过去几个月报告的许多错误。其中一些问题仅影响 9.6 版本,但许多问题影响所有受支持的版本

  • pg_upgrade:更正了有关升级备用服务器以确保主服务器和备用服务器安全同步的过程的文档。还包括一个修复程序,以确保最后一个 WAL 记录没有 "wal_level = minimum",这将阻止备用服务器在重新启动时连接
  • 修复了可能导致某些更新失败的并发锁定竞争条件的问题
  • 修复了几个低概率数据损坏场景
  • 修复了在内存中排序超过 10 亿个元组时防止崩溃的问题
  • 在 Windows 上修复了如果无法分配共享内存地址(通常由防病毒软件干扰引起)时,重试创建进程的问题
  • 修复了 libpq 中的问题,以确保正确重置使用 GSS/SASL 和 SSPI 身份验证的失败连接尝试
  • 修复了 SSL 连接处理和日志记录问题
  • 修复了允许在聚合函数的参数内的子 SELECT 语句中使用窗口函数的问题
  • 允许在从查询复制时,在查询计划中并行化
  • 修复了多个 ALTER TABLE 问题
  • 修复了以确保 ALTER USER ... SET 和 ALTER ROLE ... SET 接受相同的语法变体
  • 修复了统计信息收集器,确保在 postmaster 关闭请求后发出的统计信息请求将被写入磁盘
  • 修复了备用服务器升级期间可能创建无效 WAL 段的问题
  • 修复了几个 walsender / walreceiver 问题,特别是关于信号处理和关闭/重新启动的问题
  • 修复了多个逻辑解码问题,包括消除向磁盘泄漏小事务的问题
  • 允许在执行 CREATE FOREIGN TABLE 时,CHECK 约束最初为 NOT VALID
  • 修复了 postgres_fdw,以在 ALTER SERVER / ALTER USER MAPPING 命令后立即应用更改,并提高从无响应服务器退出的能力
  • 修复了 pg_dump 和 pg_restore 的多个问题,包括修复 Windows 上 pg_dump 输出到 stdout 的问题
  • 修复了 Windows 上 pg_basebackup 输出到 stdout 的问题,类似于修复 pg_dump
  • 修复了 pg_rewind 以正确处理超过 2GB 的文件,尽管如此大小的文件很少出现在数据目录中
  • 修复了使用 Microsoft Visual C (MSVC) 构建 PostgreSQL 的多个问题,主要围绕库的来源

9.2 版本结束生命周期警告

PostgreSQL 9.2 版本将于 2017 年 9 月结束生命周期。该项目预计只会为该版本发布一次更新。我们敦促用户尽快开始计划升级到更高版本的 PostgreSQL。有关更多信息,请参阅我们的版本控制策略。

更新

所有 PostgreSQL 更新版本都是累积的。与其他次要版本一样,用户无需转储和重新加载数据库或使用 pg_upgrade 来应用此更新版本;您可以简单地关闭 PostgreSQL 并更新其二进制文件。

链接