1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-16 17:07:43 +03:00

Restrict psql meta-commands in plain-text dumps.

A malicious server could inject psql meta-commands into plain-text
dump output (i.e., scripts created with pg_dump --format=plain,
pg_dumpall, or pg_restore --file) that are run at restore time on
the machine running psql.  To fix, introduce a new "restricted"
mode in psql that blocks all meta-commands (except for \unrestrict
to exit the mode), and teach pg_dump, pg_dumpall, and pg_restore to
use this mode in plain-text dumps.

While at it, encourage users to only restore dumps generated from
trusted servers or to inspect it beforehand, since restoring causes
the destination to execute arbitrary code of the source superusers'
choice.  However, the client running the dump and restore needn't
trust the source or destination superusers.

Reported-by: Martin Rakhmanov
Reported-by: Matthieu Denais <litezeraw@gmail.com>
Reported-by: RyotaK <ryotak.mail@gmail.com>
Suggested-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Security: CVE-2025-8714
Backpatch-through: 13
This commit is contained in:
Nathan Bossart
2025-08-11 09:00:00 -05:00
parent 70693c645f
commit 71ea0d6795
22 changed files with 435 additions and 13 deletions

View File

@@ -96,6 +96,18 @@ PostgreSQL documentation
light of the limitations listed below.
</para>
<warning>
<para>
Restoring a dump causes the destination to execute arbitrary code of the
source superusers' choice. Partial dumps and partial restores do not limit
that. If the source superusers are not trusted, the dumped SQL statements
must be inspected before restoring. Non-plain-text dumps can be inspected
by using <application>pg_restore</application>'s <option>--file</option>
option. Note that the client running the dump and restore need not trust
the source or destination superusers.
</para>
</warning>
</refsect1>
<refsect1 id="pg-dump-options">
@@ -1252,6 +1264,29 @@ PostgreSQL documentation
</listitem>
</varlistentry>
<varlistentry>
<term><option>--restrict-key=<replaceable class="parameter">restrict_key</replaceable></option></term>
<listitem>
<para>
Use the provided string as the <application>psql</application>
<command>\restrict</command> key in the dump output. This can only be
specified for plain-text dumps, i.e., when <option>--format</option> is
set to <literal>plain</literal> or the <option>--format</option> option
is omitted. If no restrict key is specified,
<application>pg_dump</application> will generate a random one as
needed. Keys may contain only alphanumeric characters.
</para>
<para>
This option is primarily intended for testing purposes and other
scenarios that require repeatable output (e.g., comparing dump files).
It is not recommended for general use, as a malicious server with
advance knowledge of the key may be able to inject arbitrary code that
will be executed on the machine that runs
<application>psql</application> with the dump output.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--rows-per-insert=<replaceable class="parameter">nrows</replaceable></option></term>
<listitem>

View File

@@ -66,6 +66,16 @@ PostgreSQL documentation
linkend="libpq-pgpass"/> for more information.
</para>
<warning>
<para>
Restoring a dump causes the destination to execute arbitrary code of the
source superusers' choice. Partial dumps and partial restores do not limit
that. If the source superusers are not trusted, the dumped SQL statements
must be inspected before restoring. Note that the client running the dump
and restore need not trust the source or destination superusers.
</para>
</warning>
</refsect1>
<refsect1>
@@ -591,6 +601,26 @@ exclude database <replaceable class="parameter">PATTERN</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--restrict-key=<replaceable class="parameter">restrict_key</replaceable></option></term>
<listitem>
<para>
Use the provided string as the <application>psql</application>
<command>\restrict</command> key in the dump output. If no restrict
key is specified, <application>pg_dumpall</application> will generate a
random one as needed. Keys may contain only alphanumeric characters.
</para>
<para>
This option is primarily intended for testing purposes and other
scenarios that require repeatable output (e.g., comparing dump files).
It is not recommended for general use, as a malicious server with
advance knowledge of the key may be able to inject arbitrary code that
will be executed on the machine that runs
<application>psql</application> with the dump output.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--rows-per-insert=<replaceable class="parameter">nrows</replaceable></option></term>
<listitem>

View File

@@ -68,6 +68,18 @@ PostgreSQL documentation
<application>pg_restore</application> will not be able to load the data
using <command>COPY</command> statements.
</para>
<warning>
<para>
Restoring a dump causes the destination to execute arbitrary code of the
source superusers' choice. Partial dumps and partial restores do not limit
that. If the source superusers are not trusted, the dumped SQL statements
must be inspected before restoring. Non-plain-text dumps can be inspected
by using <application>pg_restore</application>'s <option>--file</option>
option. Note that the client running the dump and restore need not trust
the source or destination superusers.
</para>
</warning>
</refsect1>
<refsect1 id="app-pgrestore-options">
@@ -796,6 +808,28 @@ PostgreSQL documentation
</listitem>
</varlistentry>
<varlistentry>
<term><option>--restrict-key=<replaceable class="parameter">restrict_key</replaceable></option></term>
<listitem>
<para>
Use the provided string as the <application>psql</application>
<command>\restrict</command> key in the dump output. This can only be
specified for SQL script output, i.e., when the <option>--file</option>
option is used. If no restrict key is specified,
<application>pg_restore</application> will generate a random one as
needed. Keys may contain only alphanumeric characters.
</para>
<para>
This option is primarily intended for testing purposes and other
scenarios that require repeatable output (e.g., comparing dump files).
It is not recommended for general use, as a malicious server with
advance knowledge of the key may be able to inject arbitrary code that
will be executed on the machine that runs
<application>psql</application> with the dump output.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
<listitem>

View File

@@ -70,6 +70,14 @@ PostgreSQL documentation
<application>pg_upgrade</application> supports upgrades from 9.2.X and later to the current
major release of <productname>PostgreSQL</productname>, including snapshot and beta releases.
</para>
<warning>
<para>
Upgrading a cluster causes the destination to execute arbitrary code of the
source superusers' choice. Ensure that the source superusers are trusted
before upgrading.
</para>
</warning>
</refsect1>
<refsect1>

View File

@@ -3551,6 +3551,24 @@ SELECT $1 \parse stmt1
</varlistentry>
<varlistentry id="app-psql-meta-command-restrict">
<term><literal>\restrict <replaceable class="parameter">restrict_key</replaceable></literal></term>
<listitem>
<para>
Enter "restricted" mode with the provided key. In this mode, the only
allowed meta-command is <command>\unrestrict</command>, to exit
restricted mode. The key may contain only alphanumeric characters.
</para>
<para>
This command is primarily intended for use in plain-text dumps
generated by <application>pg_dump</application>,
<application>pg_dumpall</application>, and
<application>pg_restore</application>, but it may be useful elsewhere.
</para>
</listitem>
</varlistentry>
<varlistentry id="app-psql-meta-command-s">
<term><literal>\s [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
<listitem>
@@ -3802,6 +3820,24 @@ SELECT 1 \bind \sendpipeline
</varlistentry>
<varlistentry id="app-psql-meta-command-unrestrict">
<term><literal>\unrestrict <replaceable class="parameter">restrict_key</replaceable></literal></term>
<listitem>
<para>
Exit "restricted" mode (i.e., where all other meta-commands are
blocked), provided the specified key matches the one given to
<command>\restrict</command> when restricted mode was entered.
</para>
<para>
This command is primarily intended for use in plain-text dumps
generated by <application>pg_dump</application>,
<application>pg_dumpall</application>, and
<application>pg_restore</application>, but it may be useful elsewhere.
</para>
</listitem>
</varlistentry>
<varlistentry id="app-psql-meta-command-unset">
<term><literal>\unset <replaceable class="parameter">name</replaceable></literal></term>