2025年9月25日: PostgreSQL 18 发布!

2017-08-10 安全更新发布

发布于 2017-08-10,作者:PostgreSQL 全球开发组

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”目录视图向缺乏服务器权限的用户泄露密码

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

在此修复程序之前,用户可以查看 pg_user_mappings 中的选项,即使该用户对关联的外部服务器没有 USAGE 权限。这意味着用户可以看到服务器管理员而非用户设置的密码等详细信息。

此修复程序仅会修复新创建的、使用 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. 您还需要对您的 template0template1 数据库运行此命令,否则漏洞将存在于您将来创建的数据库中。

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

    ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true;
    

    在 PostgreSQL 9.4 及更早版本中,您需要运行此命令

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

    然后,在您的 template0template1 数据库中,按第 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”,这会阻止备用服务器在重启后连接
  • 修复了并发锁定竞态条件问题,该问题可能导致部分更新失败
  • 修复了几个低概率数据损坏场景
  • 修复了在内存中对超过十亿个元组进行排序时防止崩溃
  • 修复了 Windows 上创建进程的重试机制,以防共享内存地址分配失败(通常由防病毒软件干扰引起)
  • 修复了 libpq 中确保使用 GSS/SASL 和 SSPI 身份验证的失败连接尝试得到正确重置
  • 修复了 SSL 连接处理和日志记录
  • 修复了允许在聚合函数参数内的子 SELECT 语句中使用窗口函数
  • 当从查询进行 COPY 时,允许在查询计划中使用并行复制
  • 对 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 进行了多项修复,包括修复了 pg_dump 在 Windows 上输出到 stdout 的问题
  • 修复了 pg_basebackup 在 Windows 上输出到 stdout 的问题,与 pg_dump 的修复类似
  • 修复了 pg_rewind 以正确处理超过 2GB 的文件,尽管数据目录中很少出现如此大的文件
  • 修复了使用 Microsoft Visual C (MSVC) 构建 PostgreSQL 的多项问题,主要涉及库的来源

9.2 版本终止支持警告

PostgreSQL 9.2 版本将于 2017 年 9 月停止支持。项目预计只会发布最后一个该版本的更新。我们敦促用户尽快开始计划升级到更高版本的 PostgreSQL。有关更多信息,请参阅我们的版本策略。

更新

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

链接