diff options
| author | Nathan Bossart | 2025-08-11 14:00:00 +0000 |
|---|---|---|
| committer | Nathan Bossart | 2025-08-11 14:00:00 +0000 |
| commit | 7ad8e790988d3a49010ec00e0cec0dace4c7416f (patch) | |
| tree | eb5c56a6da8a18d1d5dc814712da0331bfaec338 /doc | |
| parent | 850caae60c49c15ed021f8051dc39c6e24f2a380 (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.sgml | 35 | ||||
| -rw-r--r-- | doc/src/sgml/ref/pg_dumpall.sgml | 30 | ||||
| -rw-r--r-- | doc/src/sgml/ref/pg_restore.sgml | 34 | ||||
| -rw-r--r-- | doc/src/sgml/ref/pgupgrade.sgml | 8 | ||||
| -rw-r--r-- | doc/src/sgml/ref/psql-ref.sgml | 36 |
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=> <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> |
