doc: a restore executes code chosen by any dumped object's owner

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

Browse pgsql-hackers by date

  From Date Subject
Next Message Alexandre Felipe 2026-08-24 19:16:52 Re: SLOPE - Planner optimizations on monotonic expressions.
Previous Message Jeff Davis 2026-08-24 19:04:16 Comment and test to capture case mapping complexities