| From: | Yogesh Sharma <yogesh(dot)sharma(at)catprosystems(dot)com> |
|---|---|
| To: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Cc: | nathan(at)postgresql(dot)org |
| Subject: | doc: a restore executes code chosen by any dumped object's owner |
| Date: | 2026-08-24 19:14:39 |
| Message-ID: | baf3e5f5-6788-437c-8e79-51ead2af7365@CatProSystems.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hello Hackers,
While working on pgactive I re-read the dump/restore warning that
71ea0d6795 added to pg_dump, pg_dumpall and pg_restore:
Restoring a dump causes the destination to execute arbitrary code of
the source superusers' choice.
Scoping this to source superusers is right for the psql meta-command
vector that commit addressed, since that executes on the client. It
seems too narrow for the destination-server execution described in the
same sentence: any source role that owns a dumped object can supply code
the destination executes, and it runs with the privileges of the role
performing the restore.
Two cases I confirmed on master (9673a0aa92f), with the objects owned by
a non-superuser and the restore run by a superuser:
- A CHECK constraint is inlined into CREATE TABLE and evaluated as each
row is loaded by COPY.
- A stored generated column is omitted from the COPY column list, so its
expression is recomputed during that same load.
As the non-superuser:
CREATE FUNCTION ck(i int) RETURNS bool LANGUAGE plpgsql AS $$ BEGIN
RAISE WARNING 'ran as %', current_user; RETURN true; END $$; CREATE
TABLE t (i int CHECK (ck(i))); INSERT INTO t VALUES (1);
Dumping that and restoring as a superuser:
WARNING: ran as postgres
(RAISE NOTICE is not enough to see this — pg_dump emits SET
client_min_messages = warning.)
A domain's CHECK constraint behaves the same way.
The attached patch widens the warning's scoping and adds those two
examples. The mitigation is unchanged: inspect the dumped statements
before restoring.
The distinction matters when the source superusers are trusted but the
source's ordinary object owners are not, which is the common shape of a
multi-tenant source.
Two judgment calls in the patch, both worth a second opinion:
Index expressions are not an example of this, though they look like one.
CREATE INDEX switches to the table owner and runs the expression in a
security-restricted operation (a117cebd638), so it gains the owner
nothing. I mention it because it was my first instinct, and may be
someone else's.
pg_upgrade's reference page carries a shorter form of the same warning.
I left it alone, since pg_upgrade restores schema only — no COPY runs,
so neither expression is evaluated. Happy to update it too if that
reasoning is wrong.
71ea0d6795 was back-patched through 13, so presumably this should be as
well, but I'll leave that to the committer.
Disclaimer: Claude was used to re-verify the findings.
--
Kind Regards,
Yogesh Sharma
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Clarify-whose-code-a-restore-executes-in-the-dump.patch | text/x-patch | 5.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | Jeff Davis | 2026-08-24 19:04:16 | Comment and test to capture case mapping complexities |