summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorNathan Bossart2025-08-11 14:00:00 +0000
committerNathan Bossart2025-08-11 14:00:00 +0000
commit7ad8e790988d3a49010ec00e0cec0dace4c7416f (patch)
treeeb5c56a6da8a18d1d5dc814712da0331bfaec338 /doc
parent850caae60c49c15ed021f8051dc39c6e24f2a380 (diff)
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
Diffstat (limited to 'doc')
-rw-r--r--doc/src/sgml/ref/pg_dump.sgml35
-rw-r--r--doc/src/sgml/ref/pg_dumpall.sgml30
-rw-r--r--doc/src/sgml/ref/pg_restore.sgml34
-rw-r--r--doc/src/sgml/ref/pgupgrade.sgml8
-rw-r--r--doc/src/sgml/ref/psql-ref.sgml36
5 files changed, 143 insertions, 0 deletions
diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index ec8ea8fd985..dc1342260b6 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -92,6 +92,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">
@@ -1079,6 +1091,29 @@ PostgreSQL documentation
</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>
<para>
diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
index ba005ff19e2..1bddc8883f0 100644
--- a/doc/src/sgml/ref/pg_dumpall.sgml
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -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>
@@ -525,6 +535,26 @@ PostgreSQL documentation
</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>
<para>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
index a81583191c1..d2ff765dc74 100644
--- a/doc/src/sgml/ref/pg_restore.sgml
+++ b/doc/src/sgml/ref/pg_restore.sgml
@@ -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">
@@ -676,6 +688,28 @@ PostgreSQL documentation
</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>
<para>
diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml
index 494aa0b5bbc..0459fc3777e 100644
--- a/doc/src/sgml/ref/pgupgrade.sgml
+++ b/doc/src/sgml/ref/pgupgrade.sgml
@@ -70,6 +70,14 @@ PostgreSQL documentation
pg_upgrade 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>
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 7ff6e1d95d7..747408932a7 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -3340,6 +3340,24 @@ lo_import 152801
</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>
@@ -3514,6 +3532,24 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
</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>