Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions doc/src/sgml/ref/pg_dump.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -1070,6 +1082,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>
Expand Down
30 changes: 30 additions & 0 deletions doc/src/sgml/ref/pg_dumpall.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -588,6 +598,26 @@ 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. 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>
Expand Down
34 changes: 34 additions & 0 deletions doc/src/sgml/ref/pg_restore.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -742,6 +754,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>
Expand Down
8 changes: 8 additions & 0 deletions doc/src/sgml/ref/pgupgrade.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
41 changes: 41 additions & 0 deletions doc/src/sgml/ref/psql-ref.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -3244,6 +3244,24 @@ lo_import 152801
</varlistentry>


<varlistentry>
<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>
<term><literal>\s [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
<listitem>
Expand Down Expand Up @@ -3418,6 +3436,29 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
</varlistentry>


<varlistentry>
<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>
<para>
Unlike most other meta-commands, the entire remainder of the line is
always taken to be the argument of <command>\unrestrict</command>, and
neither variable interpolation nor backquote expansion are performed.
</para>
</listitem>
</varlistentry>


<varlistentry>
<term><literal>\unset <replaceable class="parameter">name</replaceable></literal></term>

Expand Down
38 changes: 38 additions & 0 deletions src/bin/pg_dump/dumputils.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "dumputils.h"
#include "fe_utils/string_utils.h"

static const char restrict_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

static bool parseAclItem(const char *item, const char *type,
const char *name, const char *subname, int remoteVersion,
Expand Down Expand Up @@ -920,3 +921,40 @@ makeAlterConfigCommand(PGconn *conn, const char *configitem,

pg_free(mine);
}

/*
* Generates a valid restrict key (i.e., an alphanumeric string) for use with
* psql's \restrict and \unrestrict meta-commands. For safety, the value is
* chosen at random.
*/
char *
generate_restrict_key(void)
{
uint8 buf[64];
char *ret = palloc(sizeof(buf));

if (!pg_strong_random(buf, sizeof(buf)))
return NULL;

for (int i = 0; i < sizeof(buf) - 1; i++)
{
uint8 idx = buf[i] % strlen(restrict_chars);

ret[i] = restrict_chars[idx];
}
ret[sizeof(buf) - 1] = '\0';

return ret;
}

/*
* Checks that a given restrict key (intended for use with psql's \restrict and
* \unrestrict meta-commands) contains only alphanumeric characters.
*/
bool
valid_restrict_key(const char *restrict_key)
{
return restrict_key != NULL &&
restrict_key[0] != '\0' &&
strspn(restrict_key, restrict_chars) == strlen(restrict_key);
}
3 changes: 3 additions & 0 deletions src/bin/pg_dump/dumputils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ extern void makeAlterConfigCommand(PGconn *conn, const char *configitem,
const char *type2, const char *name2,
PQExpBuffer buf);

extern char *generate_restrict_key(void);
extern bool valid_restrict_key(const char *restrict_key);

#endif /* DUMPUTILS_H */
4 changes: 4 additions & 0 deletions src/bin/pg_dump/pg_backup.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ typedef struct _restoreOptions
bool dumpSchema;
bool dumpData;
bool dumpStatistics;

char *restrict_key;
} RestoreOptions;

typedef struct _dumpOptions
Expand Down Expand Up @@ -205,6 +207,8 @@ typedef struct _dumpOptions
bool dumpSchema;
bool dumpData;
bool dumpStatistics;

char *restrict_key;
} DumpOptions;

/*
Expand Down
32 changes: 31 additions & 1 deletion src/bin/pg_dump/pg_backup_archiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ dumpOptionsFromRestoreOptions(RestoreOptions *ropt)
dopt->include_everything = ropt->include_everything;
dopt->enable_row_security = ropt->enable_row_security;
dopt->sequence_data = ropt->sequence_data;
dopt->restrict_key = ropt->restrict_key ? pg_strdup(ropt->restrict_key) : NULL;

return dopt;
}
Expand Down Expand Up @@ -473,6 +474,17 @@ RestoreArchive(Archive *AHX)

ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");

/*
* If generating plain-text output, enter restricted mode to block any
* unexpected psql meta-commands. A malicious source might try to inject
* a variety of things via bogus responses to queries. While we cannot
* prevent such sources from affecting the destination at restore time, we
* can block psql meta-commands so that the client machine that runs psql
* with the dump output remains unaffected.
*/
if (ropt->restrict_key)
ahprintf(AH, "\\restrict %s\n\n", ropt->restrict_key);

if (AH->archiveRemoteVersion)
ahprintf(AH, "-- Dumped from database version %s\n",
AH->archiveRemoteVersion);
Expand Down Expand Up @@ -749,6 +761,14 @@ RestoreArchive(Archive *AHX)

ahprintf(AH, "--\n-- PostgreSQL database dump complete\n--\n\n");

/*
* If generating plain-text output, exit restricted mode at the very end
* of the script. This is not pro forma; in particular, pg_dumpall
* requires this when transitioning from one database to another.
*/
if (ropt->restrict_key)
ahprintf(AH, "\\unrestrict %s\n\n", ropt->restrict_key);

/*
* Clean up & we're done.
*/
Expand Down Expand Up @@ -3335,11 +3355,21 @@ _reconnectToDB(ArchiveHandle *AH, const char *dbname)
else
{
PQExpBufferData connectbuf;
RestoreOptions *ropt = AH->public.ropt;

/*
* We must temporarily exit restricted mode for \connect, etc.
* Anything added between this line and the following \restrict must
* be careful to avoid any possible meta-command injection vectors.
*/
ahprintf(AH, "\\unrestrict %s\n", ropt->restrict_key);

initPQExpBuffer(&connectbuf);
appendPsqlMetaConnect(&connectbuf, dbname);
ahprintf(AH, "%s\n", connectbuf.data);
ahprintf(AH, "%s", connectbuf.data);
termPQExpBuffer(&connectbuf);

ahprintf(AH, "\\restrict %s\n\n", ropt->restrict_key);
}

/*
Expand Down
Loading