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

安全:发现两个新问题

发布于 2005-05-02

我们目前正在准备新的版本,这些版本将修复新 initdb 初始化安装中的这些问题。然而,由于这些问题实际上是错误的系统目录条目,因此仅更新到新版本本身并不能解决现有安装中的问题。相反,数据库管理员需要按照下文所述手动修复目录条目。我们发布此公告是为了鼓励 PostgreSQL 安装的管理员尽快执行这些修复。

字符转换漏洞

这两个错误中比较严重的一个是,支持客户端到服务器字符集转换的函数可以被未授权用户从 SQL 命令调用,但这些函数的设计并未考虑到恶意选择参数值的安全性。此问题存在于 PostgreSQL 7.3.* 到 8.0.* 版本中。推荐的修复方法是禁用这些函数的公共 EXECUTE 访问权限。这不会影响函数的正常字符集转换用途,但可以防止滥用。

要完成此更改,请以超级用户的身份执行以下 SQL 命令

``

UPDATE pg_proc SET proacl = '{=}'

WHERE pronamespace = 11 AND pronargs = 5

AND proargtypes[2] = 'cstring'::regtype;

在 7.3.* 到 8.0.* 版本中,这应该报告更新了 90 行。7.4 及更高版本将报告“警告:默认授予者为用户 ID 1”,此警告可以忽略。

上述命令必须在安装的*每个*数据库中执行,包括 template1,最好也包括 template0。如果您不修复模板数据库,那么任何后续创建的数据库都会包含相同的漏洞。template1 可以像任何其他数据库一样修复,但修复 template0 需要额外的步骤。首先,从任何数据库执行

``

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

接下来连接到 template0 并执行 pg_proc 更新。最后,执行

``

-- 重新冻结 template0

VACUUM FREEZE;

-- 并保护其免受未来更改

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

tsearch2 漏洞

另一个错误是 contrib/tsearch2 模块错误地将几个函数声明为返回类型“internal”,而它们实际上没有任何“internal”参数。这破坏了“internal”类型的安全性,因为它允许用户构造可以调用接受“internal”参数的其他函数的 SQL 命令。此问题的后果尚未详细研究,但至少有可能导致后端崩溃。

此错误影响 PostgreSQL 7.4 及更高版本,但前提是您已安装了 contrib/tsearch2 模块。推荐的修复方法是更改错误声明的函数,使其接受一个“internal”参数,从而无法直接从 SQL 命令调用它们。

要做到这一点,请以超级用户的身份执行以下命令

``

UPDATE pg_proc SET proargtypes[0] = 'internal'::regtype

WHERE oid IN (

'dex_init(text)'::regprocedure,

'snb_en_init(text)'::regprocedure,

'snb_ru_init(text)'::regprocedure,

'spell_init(text)'::regprocedure,

'syn_init(text)'::regprocedure

);

这应该会报告更新了 5 行。(如果出现类似“函数“dex_init(text)”不存在”的消息,则表示该数据库中未安装 tsearch2,或者您已经执行了更新。)

您需要在已安装 tsearch2 的*每个*数据库中执行此操作,包括 template1。不过,您无需担心 template0,因为它肯定不包含 tsearch2。

如果您经常在新数据库中安装 tsearch2,您可能还需要修改 tsearch.sql 脚本,以便从一开始就声明这些函数接受 internal 类型。(脚本修复将成为即将发布的版本的一部分,因此您可能可以等到那些版本发布。)

我谨代表 PostgreSQL 核心委员会,对这些错误可能带来的任何问题表示歉意。

此致,tom lane

本文已从先前版本的 PostgreSQL 网站迁移。对于迁移过程中可能出现的任何格式问题,我们深表歉意。