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

PostgreSQL 17.1、16.5、15.9、14.14、13.17 和 12.21 已发布!

发布于 2024-11-14,作者 PostgreSQL Global Development Group
PostgreSQL 项目 安全

PostgreSQL 全球开发组已发布所有受支持版本的 PostgreSQL 更新,包括 17.1、16.5、15.9、14.14、13.17 和 12.21。此次发布修复了过去几个月报告的 4 个安全漏洞和 35 个以上的错误。

有关更改的完整列表,请参阅 发行说明

PostgreSQL 12 EOL 通知

这是 PostgreSQL 12 的最终版本。PostgreSQL 12 现已达到生命周期终点,将不再接收安全和错误修复。如果您在生产环境中使用 PostgreSQL 12,我们建议您计划升级到更新的、受支持的 PostgreSQL 版本。请参阅我们的 版本策略 以获取更多信息。

安全问题

CVE-2024-10976:PostgreSQL 行安全策略在子查询等情况下会忽略用户 ID 更改

CVSS v3.1 基本评分:4.2

受支持且存在漏洞的版本:12 - 17。

PostgreSQL 中对带有行安全策略的表跟踪不完整,允许重复使用的查询查看或更改与预期不同的行。 CVE-2023-2455CVE-2016-2193 修复了行安全策略和用户 ID 更改之间的绝大多数交互。它们遗漏了子查询、WITH 查询、安全调用者视图或 SQL 语言函数引用带有行级安全策略的表的情况。这与之前的两个 CVE 具有相同的后果。也就是说,在使用了基于角色的策略,并且给定的查询在一个角色下规划,然后又在其他角色下执行的情况下,可能导致应用了不正确的策略。这种情况可能发生在安全定义者函数中,或者当一个通用用户和查询最初被规划,然后跨多个 SET ROLE 被重复使用时。

应用不正确的策略可能会允许用户完成原本被禁止的读取和修改。这仅影响使用了 CREATE POLICY 定义了行安全策略的数据库。攻击者必须根据特定应用程序的查询计划重用模式、用户 ID 更改和基于角色的行安全策略来定制攻击。PostgreSQL 17.1、16.5、15.9、14.14、13.17 和 12.21 之前的版本受到影响。

PostgreSQL 项目感谢 Wolfgang Walther 报告此问题。

CVE-2024-10977:PostgreSQL libpq 保留了中间人攻击产生的错误消息

CVSS v3.1 基本评分:3.1

受支持且存在漏洞的版本:12 - 17。

PostgreSQL 中客户端对服务器错误消息的使用允许在当前 SSL 或 GSS 设置下不受信任的服务器向 libpq 应用程序提供任意非 NUL 字节。例如,中间人攻击者可以发送一条长错误消息,使得 psql 的人类用户或屏幕抓取器将其误认为是有效的查询结果。对于用户界面明确区分错误消息与其他文本边界的客户端来说,这可能不是一个问题。PostgreSQL 17.1、16.5、15.9、14.14、13.17 和 12.21 之前的版本受到影响。

PostgreSQL 项目感谢 Jacob Champion 报告此问题。

CVE-2024-10978:PostgreSQL SET ROLE、SET SESSION AUTHORIZATION 重置为错误的用户 ID

CVSS v3.1 基本评分:4.2

受支持且存在漏洞的版本:12 - 17。

PostgreSQL 中不正确的权限分配允许权限较低的应用程序用户查看或更改与预期不同的行。攻击需要应用程序使用 SET ROLESET SESSION AUTHORIZATION 或等效功能。当应用程序查询使用攻击者的参数或将查询结果传达给攻击者时,会产生此问题。如果该查询响应 current_setting('role') 或当前用户 ID,它可能会修改或返回数据,就好像会话没有使用 SET ROLESET SESSION AUTHORIZATION 一样。攻击者无法控制应用哪个不正确的用户 ID。来自较低权限源的查询文本在此处不是问题,因为 SET ROLESET SESSION AUTHORIZATION 不是未经验证的查询的沙箱。PostgreSQL 17.1、16.5、15.9、14.14、13.17 和 12.21 之前的版本受到影响。

PostgreSQL 项目感谢 Tom Lane 报告此问题。

CVE-2024-10979:PostgreSQL PL/Perl 环境变量更改执行任意代码

CVSS v3.1 基本评分:8.8

受支持且存在漏洞的版本:12 - 17。

PostgreSQL PL/Perl 中环境变量控制不当,允许未授权的数据库用户更改敏感进程环境变量(例如 PATH)。这通常足以实现任意代码执行,即使攻击者没有数据库服务器操作系统用户。PostgreSQL 17.1、16.5、15.9、14.14、13.17 和 12.21 之前的版本受到影响。

PostgreSQL 项目感谢 Coby Abrams 报告此问题。

错误修复和改进

此次更新修复了过去几个月报告的 35 个以上错误。以下列出的问题影响 PostgreSQL 17。其中一些问题也可能影响 PostgreSQL 的其他受支持版本。

  • 修复了在具有外键约束的分区表之间附加或分离分区时出现的问题。升级后,受此问题影响的用户需要执行手动步骤来完成修复。请参阅“升级”部分和发行说明以获取更多信息。
  • 修复了在使用 libc 作为默认排序规则提供程序时,当 LC_CTYPECLC_COLLATE 是不同区域设置时出现的问题。这可能导致查询结果不正确。如果您的数据库中存在这些设置,请在更新到此版本后重新索引任何受影响的索引。此问题仅影响 17.0。
  • 对查询规划器进行了多项修复,包括在分区排序规则不匹配时禁止执行分区连接(partitionwise join)。
  • 修复了 MERGE ... WHEN NOT MATCHED BY SOURCE 操作可能出现的错误答案或 wrong varnullingrels 规划器错误。
  • 修复了 COPY 命令中的 FORCE_NOT_NULLFORCE_NULL 的验证。
  • 修复了当 json_objectagg() 调用包含易失性函数时服务器崩溃的问题。
  • 确保在分区表和 CREATE TABLE ... USING 中指定的非内置访问方法之间存在已注册的依赖关系。此修复仅防止在更新后创建的分区表出现问题。
  • 修复了提交可串行化事务时的竞态条件。
  • 修复了 COMMIT PREPARED 中的竞态条件,该条件在崩溃和恢复后可能需要手动删除文件。
  • 修复了 pg_cursors 视图,通过排除尚未完全设置的游标来防止错误。
  • 减少了逻辑解码的内存消耗。
  • 修复了防止稳定函数在从 CALL 语句的参数列表中调用,并且该 CALL 位于 PL/pgSQL EXCEPTION 块中时,接收到过时的行值。
  • 修复了 ARM (aarch64) 系统上的 JIT 崩溃问题。
  • psql\watch 命令现在将小于 1 毫秒的值视为 0(执行之间不等待)。
  • 修复了在 密码文件pgpass)中使用复制用户凭据失败的问题。
  • pg_combinebackup 现在如果增量备份文件出现在本应包含完整备份的目录中时会抛出错误。
  • 修复了以避免在 vacuumdb 和并行 reindexdb 中对临时表和索引进行重复索引。

此版本还更新了时区数据文件到 tzdata release 2024b。此 tzdata 版本将旧的 System-V 兼容时区名称更改为复制相应的地理时区;例如 PST8PDT 现在是 America/Los_Angeles 的别名。主要可见的后果是,对于标准化时区引入之前的时间戳,该时区被认为代表命名地点的本地平均太阳时。例如,在 PST8PDT 中,时间戳输入(如 1801-01-01 00:00)以前会显示为 1801-01-01 00:00:00-08,但现在它显示为 1801-01-01 00:00:00-07:52:58

此外,对墨西哥、蒙古和葡萄牙进行了历史性修正。值得注意的是,Asia/Choibalsan 现在是 Asia/Ulaanbaatar 的别名,而不是一个单独的时区,这主要是因为这些时区之间的差异被发现基于不可靠的数据。

更新

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

如果您有一个带有外键约束的分区表,并且您已执行 ATTACH PARTITION/DETACH PARTITION 命令,您将在升级后需要采取进一步措施。您可以通过对每个有问题的约束执行 ALTER TABLE ... DROP CONSTRAINT 命令,然后重新添加约束来解决此问题。如果重新添加约束失败,您需要手动重新建立引用表和被引用表之间的一致性,然后重新添加约束。

此查询可用于识别损坏的约束并构建重新创建它们的命令。

SELECT conrelid::pg_catalog.regclass AS "constrained table", conname AS constraint, confrelid::pg_catalog.regclass AS "references", pg_catalog.format('ALTER TABLE %s DROP CONSTRAINT %I;', conrelid::pg_catalog.regclass, conname) AS "drop", pg_catalog.format('ALTER TABLE %s ADD CONSTRAINT %I %s;', conrelid::pg_catalog.regclass, conname, pg_catalog.pg_get_constraintdef(oid)) AS "add" FROM pg_catalog.pg_constraint c WHERE contype = 'f' AND conparentid = 0 AND (SELECT count(*) FROM pg_catalog.pg_constraint c2 WHERE c2.conparentid = c.oid) <> (SELECT count(*) FROM pg_catalog.pg_inherits i WHERE (i.inhparent = c.conrelid OR i.inhparent = c.confrelid) AND EXISTS (SELECT 1 FROM pg_catalog.pg_partitioned_table WHERE partrelid = i.inhparent));

由于一个或多个 ADD CONSTRAINT 步骤可能失败,您应该将查询的输出保存到文件中,然后尝试执行每个步骤。

此外,如果您正在运行 PostgreSQL 17.0 并且使用 libc 作为您的默认排序规则提供程序,并将 LC_CTYPE 设置为 C,同时 LC_COLLATE 是不同的区域设置,您将需要重建您的基于文本的索引。您可以使用 REINDEX INDEX CONCURRENTLY 命令来完成此操作。

跳过一个或多个更新版本的用户可能需要运行额外的更新后步骤;请参阅早期版本的发行说明以获取详细信息。

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

链接

如果您对此版本公告有任何更正或建议,请将其发送至 pgsql-www@lists.postgresql.org 公共 邮件列表